ffmpeg 从几个选定的时间点提取图片

Jak*_*ter 4 video ffmpeg extract frame

我有一个视频文件,喜欢从(大约 1500 个)特定时间点提取单个图像。(expl. -ss 00:50, ss 00:67, ss: 01:70 ...)

有没有办法做到这一点?我尝试使用这个命令:

ffmpeg.exe -ss 00:50 -i all.avi -t 00:00:01 -vframes 1 images-filename_%03d.png
Run Code Online (Sandbox Code Playgroud)

这对于单张图片非常有用,但是有没有办法针对如此多的特定时间点执行此操作?

有没有人有建议?

小智 12

这个答案改进了@slhck答案,在某些情况下可能无法正常工作。

通过(近似)时间戳选择帧的一个微妙之处是帧的实际时间戳可能不完全等于所需的时间戳。例如,在帧率为 23.98 (24000/1001) 的视频中,没有时间戳为 1.0 的帧 - 最接近的帧的时间戳值为 1.001。

eq(t, specific_timepoint)仅当t完全等于 时,表达式才计算为真specific_timepoint。因此,在上述情况下将无法选择帧。作为一种解决方法,我们可以选择紧跟在所需时间戳之后的第一帧,即时间戳值大于或等于指定时间点的帧,而其前一帧的时间戳小于指定时间点。单个时间点的选择表达式将为

lt(prev_pts * TB,timepoint) * gte(pts * TB,timepoint)

请注意,我故意没有使用较短的变体

between(timepoint, prev_pts*TB, pts*TB)

这相当于

lte(prev_pts * TB,timepoint) * gte(pts * TB,timepoint)

因为当(第一个)其中一个的时间戳值指定的时间点值完全匹配时,它将选择两个连续的帧。

选择与时间点 1.5、10 和 20 对应或紧随其后的帧的示例:

ffmpeg -i input.mp4 -filter:v \
    "select='lt(prev_pts*TB\,1.5)*gte(pts*TB\,1.5) \
            +lt(prev_pts*TB\,10)*gte(pts*TB\,10)   \
            +lt(prev_pts*TB\,20)*gte(pts*TB\,20)'" \
    -vsync drop images-filename_%03d.png
Run Code Online (Sandbox Code Playgroud)


slh*_*hck 3

添加多个时间戳作为select过滤器的选项。

ffmpeg -i input.mp4 -filter:v \
"select='eq(t\,1.5)+eq(t\,10)+eq(t\,20)'" \
-vsync drop images-filename_%03d.png
Run Code Online (Sandbox Code Playgroud)

如果过滤器评估为 true,它将输出一个帧,因此添加将帧时间戳t与以秒为单位的特定时间戳进行比较的检查(例如,1.5)将为您提供这些时间戳处的所有帧。