import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:path_provider/path_provider.dart'; import 'package:video_thumbnail/video_thumbnail.dart'; class VideoThumbnailImage extends StatefulWidget { final String videoUrl; const VideoThumbnailImage({Key? key, required this.videoUrl}) : super(key: key); @override _VideoThumbnailState createState() => _VideoThumbnailState(); } class _VideoThumbnailState extends State { // ✅ 使用 static 缓存:所有实例共享,避免重复请求 static final Map> _pendingThumbnails = {}; late Future _thumbnailFuture; @override void initState() { super.initState(); // ✅ 如果已存在该 URL 的 Future,复用;否则创建并缓存 _thumbnailFuture = _pendingThumbnails.putIfAbsent(widget.videoUrl, () { return _generateThumbnail(widget.videoUrl); }); } // 生成缩略图(只执行一次 per URL) Future _generateThumbnail(String url) async { try { final tempDir = await getTemporaryDirectory(); final thumbnail = await VideoThumbnail.thumbnailFile( video: url, thumbnailPath: tempDir.path, imageFormat: ImageFormat.JPEG, maxHeight: 200, quality: 100, ); return thumbnail; } catch (e) { print('Failed to generate thumbnail: $e'); return null; } } @override Widget build(BuildContext context) { return FutureBuilder( future: _thumbnailFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator()); } else if (snapshot.hasError || !snapshot.hasData) { return Center( child: Image.asset( 'images/icon_unHaveData.png', fit: BoxFit.cover, ), ); } else { return Stack( alignment: Alignment.center, children: [ RotatedBox( quarterTurns: -1, child: Image.file( File(snapshot.data!), width: 200, height: 200, fit: BoxFit.cover, ), ), Icon( Icons.play_arrow_rounded, size: 88.sp, color: Colors.white.withOpacity(0.8), ), ], ); } }, ); } }