使用video_thumbnail包无法生成不同时间帧缩略图求助
video_thumbnail生成所有缩略图均为第一帧的解决方法
可能的原因及对应解决方案
1. 时间点计算集中在视频开头,且关键帧间隔过大
你的时间点计算逻辑totalMilliSecs ~/10 *i会让前几个采样点(如0ms、1748ms)集中在视频最开头,若视频的关键帧间隔大于采样间隔,video_thumbnail会默认提取最近的关键帧,导致所有缩略图都是第一帧。
调整时间点计算逻辑,让采样点均匀覆盖整个视频时长:
for (int i = 0; i < 10; i++) { // 将采样点分布在总时长的1/10到10/10区间,避免集中在开头 int ms = (totalMilliSecs * (i + 1)) ~/ 10; // 避免取到视频结尾可能的黑屏帧,减去100ms if (ms >= totalMilliSecs) { ms = totalMilliSecs - 100; } // 后续缩略图生成代码 }
2. 临时文件缓存/覆盖问题
video_thumbnail的thumbnailFile方法若不指定name参数,可能复用临时文件名,导致后续生成的缩略图覆盖之前的文件,最终列表中所有路径指向同一帧。
为每个缩略图指定唯一名称,避免文件冲突:
final thumbnailPath = await VideoThumbnail.thumbnailFile( video: videoFile!.path, timeMs: ms, name: 'recording_thumb_$i', // 用索引标识唯一文件名 maxHeight: 200, // 可选,统一缩略图尺寸 quality: 75); if (thumbnailPath != null) { recordingThumbnailsPaths[i] = thumbnailPath; } else { print('生成第$i张缩略图失败'); }
3. 使用FFmpeg实现精确帧提取
若上述方法无效,说明视频编码的关键帧间隔过大,video_thumbnail无法提取非关键帧。此时可使用ffmpeg_kit_flutter直接调用FFmpeg命令,不受关键帧限制。
- 首先添加依赖到
pubspec.yaml:dependencies: ffmpeg_kit_flutter: ^5.1.0 - 修改提取逻辑:
import 'package:ffmpeg_kit_flutter/ffmpeg_kit.dart'; import 'package:path_provider/path_provider.dart'; Future<void> getRecordingThumbnailsPaths() async { final int totalMilliSecs = (await FlutterVideoInfo().getVideoInfo(videoFile!.path))! .duration! .toInt(); final tempDir = await getTemporaryDirectory(); for (int i = 0; i < 10; i++) { int ms = (totalMilliSecs * (i + 1)) ~/ 10; if (ms >= totalMilliSecs) ms = totalMilliSecs - 100; final timeInSec = ms / 1000; final savePath = '${tempDir.path}/thumb_$i.jpg'; // 执行FFmpeg命令提取指定时间点的单帧 final session = await FFmpegKit.execute( '-i "${videoFile!.path}" -ss $timeInSec -vframes 1 -q:v 2 "$savePath"', ); final returnCode = await session.getReturnCode(); if (returnCode.isSuccess()) { recordingThumbnailsPaths[i] = savePath; } else { print('第$i张缩略图提取失败'); } } }
额外注意事项
- 避免用
!强制解包thumbnailFile的返回值,添加空值判断防止崩溃; - 若使用FFmpeg,需注意Android/iOS平台的权限配置(如iOS需在
Info.plist添加临时文件访问权限)。
内容的提问来源于stack exchange,提问作者sm-sayedi
相关产品推荐
相关产品推荐

