ffmpeg:如果超过阈值则减少fps,但如果低于阈值则不增加

时间:2017-04-10 23:13:05

标签: video ffmpeg

ffmpeg CLI允许您指定-r <fps>-vf fps=<fps>为您的输出设置固定的FPS。

我想要的行为是:

  • 输入可以有任意FPS(可能是20-120)。
  • 如果输入FPS> 30,则将其降低至30 FPS。
  • 如果输入FPS <= 30,请不要修改FPS。

更多背景信息:

前面提到的选项非常适合将视频标准化为固定的FPS,但不能很好地确保视频无法有效地超过某个FPS阈值。实际上,如果我设置-r 30并且视频是29 fps,那么当我的用例不需要时,ffmpeg会向我们提供大量的CPU以将其提升到30。 / p>

1 个答案:

答案 0 :(得分:2)

这可以在恒定帧速率视频上完成 - 我的下面的方法可能适用于VFR视频,但我没有合适的视频可供测试。

基本命令:

ffmpeg -i 120.mp4 -vf "select='eq(n,0)+if(gt(t-prev_selected_t,1/30.01),1,0)'" -vsync 0 out.mp4

在120 fps的流上,

Video: h264 (High) ... 120 fps, 120 tbr, 15360 tbn, 240 tbc

这会产生

Video: h264 (High) ... 30.08 fps, 30 tbr, 15360 tbn, 240 tbc

在选择第一帧之后,选择过滤器的作用是,如果它们与先前选择的帧的间隔是1/30秒或更多,则仅选择其他帧。实际上,这会将视频抽取到30 fps以下。

有两点需要注意:

1)最后一帧的持续时间被截断,因此fps值将略大于目标。但所有其他帧的帧周期为30 fps。

2)输出帧速率是将源速率除以整数得到的最高数。因此,如果在命令中30.0126替换,则结果将为24 tbr,因为通过将120除以整数,都不能获得25和26。这有利于避免输出中的运动停顿。命令中的除数应略大于上限,即30.01而不是30。否则,结果会摇摆不定。

如果输入为30 fps或更低,则选择所有帧。

<强>附录

如果将上述命令的输出传送到另一个ffmpeg实例,则输出fps是准确的,并且编解码器速率tbc也会被重置。

ffmpeg -i 120.mp4 -vf "select='eq(n,0)+if(gt(t-prev_selected_t,1/30.01),1,0)'" -vsync 0
        -c:v rawvideo -c:a pcm_s16le -f nut - | ffmpeg -f nut -i - out.mp4