如何用FFmpeg从指定时间范围提取关键帧并保留原视频时间戳命名?
FFmpeg提取关键帧+原视频时间戳命名的解决办法
问题拆解
你已经用skip_frame nokey加select滤镜的组合,成功批量抓取指定时间段的关键帧,但新版FFmpeg里,之前依赖-vsync 0 -r 10 -frame_pts true的时间戳命名方法会触发参数冲突报错;换成-fps_mode passthrough虽然能拿到正确的关键帧集合,可文件名又无法对应原视频的时间点,查找起来非常麻烦。
直接可用的解决方案
利用FFmpeg自带的输出文件名变量,就能直接将原视频的时间戳嵌入文件名,无需纠结旧参数冲突问题,直接修改输出文件名模板即可:
最终命令
ffmpeg -skip_frame nokey -i "input.mp4" -vf "select='between(t,15,25)+between(t,40,50)+between(t,95,105)+between(t,120,130)+between(t,190,200)',scale='min(480,iw)':-2:flags=lanczos" -fps_mode passthrough -copyts -c:v libwebp -quality 75 -preset photo -frame_pts true "frame_%{pts:seconds:0.3f}.webp"
关键细节说明
%{pts:seconds:0.3f}:这是实现时间戳命名的核心,它会提取帧在原视频中的精确时间戳(单位:秒),0.3f表示保留3位小数(毫秒精度),可根据需求调整:- 要十分之一秒精度:
%{pts:seconds:0.1f} - 只要整数秒:
%{pts:seconds:d}
- 要十分之一秒精度:
-copyts:必须添加,确保帧的时间戳与原视频完全对齐,是文件名变量能获取正确时间的前提-frame_pts true:配合时间戳变量使用,让FFmpeg正确解析帧的原始时间点-fps_mode passthrough:保留关键帧的原始状态,避免强制补帧生成冗余文件
老版本FFmpeg兼容方案
如果你的FFmpeg版本不支持上述文件名变量,可以通过滤镜调整时间基,将时间戳转为整数命名:
ffmpeg -skip_frame nokey -i "input.mp4" -vf "select='between(t,15,25)+between(t,40,50)+between(t,95,105)+between(t,120,130)+between(t,190,200)',scale='min(480,iw)':-2:flags=lanczos,settb=1/1000,setpts=PTS-STARTPTS" -fps_mode passthrough -copyts -c:v libwebp -quality 75 -preset photo -frame_pts true "frame_%06d.webp"
这里settb=1/1000将时间基设置为毫秒,%06d会输出6位数字的毫秒数,比如原视频15秒234毫秒处的帧会被命名为frame_015234.webp。
验证方法
运行命令后,查看输出文件名,比如frame_15.234.webp,用播放器定位到原视频15.234秒的位置,确认帧内容完全匹配即可。
内容的提问来源于stack exchange,提问作者Display Name
相关产品推荐
相关产品推荐

