我正在尝试从视频中提取少量帧,如下所示:
ffmpeg -i input.mp4 -vf 'select=eq(n\,1395)+eq(n\,2790)+eq(n\,4185)+eq(n\,5580)' \
'img%01d.jpg'
但是,我得到的结果是,ffmpeg 提取了视频中的所有帧,而不仅仅是我想要的帧。我该怎么做才能做得更好?
答案1
我们可以补充-vsync 0
或-fps_mode:v passthrough
论证:
对于较新版本的 FFmpeg,添加-fps_mode
:
ffmpeg -i input.mp4 -fps_mode:v passthrough -vf "select='eq(n\,1395)+eq(n\,2790)+eq(n\,4185)+eq(n\,5580)'" img%01d.jpg
对于旧版本的 FFmpeg 使用vsync
:
ffmpeg -vsync 0 -i input.mp4 -vf "select='eq(n\,1395)+eq(n\,2790)+eq(n\,4185)+eq(n\,5580)'" img%01d.jpg
执行FFmpeg时,出现警告信息:“重复的帧数超过1000”。
输出的图像并不是输入的所有视频帧,而是同一帧的大量重复。
第1395帧多次重复,然后是第2790帧的重复……
FFmpeg 重复这些帧是为了实现恒定的输出帧率。
原因是默认设置fps_mode
是auto (-1)
适用的“根据多路复用器功能在 cfr 和 vfr 之间进行选择。”.
cfr
被选中,因此“将复制并丢弃帧以准确实现所要求的恒定帧速率”。
为实现“恒定”(输出)帧,最后选定的帧被复制,直到下一个选定的帧……
测试:
构建带有帧计数器的 10fps 输入视频(用于测试)
ffmpeg -y -f lavfi -r 10 -i testsrc=size=192x108:rate=1:duration=6000 -vf setpts=N/10/TB -c:v libx264 -pix_fmt yuv420p input.mp4
:。
执行:
ffmpeg -i input.mp4 -fps_mode:v passthrough -vf "select=eq(n\,1395)+eq(n\,2790)+eq(n\,4185)+eq(n\,5580)" img%01d.jpg
输出为 4 张 JPEG 图像:
img1.jpg
,img2.jpg
,img3.jpg
,img4.jpg
:
,,,
在 Windows 10 下使用 FFmpeg 版本 5.1.2-full_build-www.gyan.dev 进行测试。