98 lines
3.0 KiB
Dart
98 lines
3.0 KiB
Dart
import 'dart:io'; // 导入 dart:io 以使用 File 类
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/widgets.dart';
|
|
import 'package:path_provider/path_provider.dart'; // 导入 path_provider
|
|
import 'package:video_thumbnail/video_thumbnail.dart'; // 导入 video_thumbnail
|
|
|
|
class VideoThumbnailImage extends StatefulWidget {
|
|
final String videoUrl;
|
|
|
|
VideoThumbnailImage({required this.videoUrl});
|
|
|
|
@override
|
|
_VideoThumbnailState createState() => _VideoThumbnailState();
|
|
}
|
|
|
|
class _VideoThumbnailState extends State<VideoThumbnailImage> {
|
|
final Map<String, String> _thumbnailCache = {}; // 缩略图缓存
|
|
late Future<String?> _thumbnailFuture; // 用于存储缩略图生成的 Future
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_thumbnailFuture = _generateThumbnail(); // 在 initState 中初始化 Future
|
|
}
|
|
|
|
// 生成缩略图
|
|
Future<String?> _generateThumbnail() async {
|
|
try {
|
|
// 检查缓存中是否已有缩略图
|
|
if (_thumbnailCache.containsKey(widget.videoUrl)) {
|
|
return _thumbnailCache[widget.videoUrl];
|
|
}
|
|
|
|
// 获取临时目录路径
|
|
final tempDir = await getTemporaryDirectory();
|
|
final thumbnailPath = await VideoThumbnail.thumbnailFile(
|
|
video: widget.videoUrl,
|
|
// 视频 URL
|
|
thumbnailPath: tempDir.path,
|
|
// 缩略图保存路径
|
|
imageFormat: ImageFormat.JPEG,
|
|
// 缩略图格式
|
|
maxHeight: 200,
|
|
// 缩略图最大高度
|
|
quality: 100, // 缩略图质量 (0-100)
|
|
);
|
|
|
|
// 更新缓存
|
|
_thumbnailCache[widget.videoUrl] = thumbnailPath!;
|
|
return thumbnailPath;
|
|
} catch (e) {
|
|
print('Failed to generate thumbnail: $e');
|
|
return null;
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return FutureBuilder<String?>(
|
|
future: _thumbnailFuture, // 生成缩略图的 Future
|
|
builder: (context, snapshot) {
|
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
|
// 加载中显示转圈
|
|
return Center(child: CircularProgressIndicator());
|
|
} else if (snapshot.hasError || !snapshot.hasData) {
|
|
// 加载失败或没有数据时显示提示
|
|
return Image.asset(
|
|
'images/icon_unHaveData.png', // 错误图片路径
|
|
fit: BoxFit.cover,
|
|
);
|
|
} else {
|
|
// 加载成功,显示缩略图
|
|
final thumbnailPath = snapshot.data!;
|
|
return Stack(
|
|
alignment: Alignment.center,
|
|
children: <Widget>[
|
|
RotatedBox(
|
|
quarterTurns: -1,
|
|
child: Image.file(
|
|
File(thumbnailPath), // 显示生成的缩略图
|
|
width: 200,
|
|
height: 200,
|
|
fit: BoxFit.cover,
|
|
),
|
|
),
|
|
Icon(
|
|
Icons.play_arrow_rounded,
|
|
size: 80,
|
|
color: Colors.white.withOpacity(0.8),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
},
|
|
);
|
|
}
|
|
}
|