我不想为 FFMPEG/libx264 (-r/-framerate) 提供固定帧速率,而是希望指定一个具有最大值的可变帧速率,并允许 libx264 根据需要降低帧速率。这里的想法是当出现诸如扩展静态帧之类的情况时获得额外的压缩(这种情况会发生很多在我的源视频中)。
我意识到预测或双向 MPEG 帧的压缩效果会很好,但源帧速率也可能小于我想要转码的帧速率(可能会导致更大的流!)。
答案1
很遗憾你也没有找到答案,我至少要回答其他人关于如何启用 VFR(不是 V乙R)来自 FFMPEG 的输出。
答案是这个名字奇怪的-vsync
选项。您可以将其设置为几个不同的选项,但您想要的是“2”或vfr
。从手册页:
-垂直同步 范围
视频同步方法。出于兼容性原因,旧值可以指定为数字。新添加的值必须始终指定为字符串。
0,直通
- 每个帧都带有其时间戳,从解复用器传递到复用器。
1、到岸价
- 将复制并删除帧以准确实现所要求的恒定帧速率。
2、vfr
- 帧连同其时间戳一起传递或者被丢弃,以防止两帧具有相同的时间戳。
降低
- 作为直通但销毁所有时间戳,使得多路复用器根据帧速率生成新的时间戳。
-1,自动
- 根据多路复用器功能在 1 和 2 之间进行选择。这是默认方法。
注意,此后,复用器可能会进一步修改时间戳。例如,在格式选项避免负面情绪已启用。
使用 -map 您可以选择从哪个流中获取时间戳。您可以保持视频或音频不变,并将其余流同步到未改变的流。
然而,我的声誉还不够高,无法发表评论来回答每个人似乎都有的“子问题”。但我确实有一些想法,说实话,我对此并不十分乐观……但我尝试的第一个想法实际上工作。 所以。
您只需将-vsync 2
选项与-r $maxfps
选项组合起来,当然,您要用$maxfps
您想要的最大帧速率替换它!而且它有效!它不会从源文件中复制帧,但它会丢弃导致文件超过最大帧速率的帧!
默认情况下,它本身似乎-r $maxfps
只会导致它复制/丢弃帧以实现恒定的帧速率,并且-vsync 2
它本身会导致它直接拉入帧而不会真正影响 PTS 值。
我对此并不乐观,因为我已经知道这会-r $maxfps
使其保持恒定的帧速率。老实说,我预计会出现错误,或者它会遵循先到或后到的顺序。事实上,它完全按照我的要求执行,这让我对 FFMPEG 开发人员非常满意。
我希望这对您有所帮助,或者如果您不再需要知道这一点的话,以后也能对其他人有所帮助。
答案2
我想指定一个可变帧速率,并设置一个最大值,然后允许 libx264 根据需要降低帧速率。这里的想法是,当出现诸如扩展静态帧之类的情况时,获得额外的压缩
据我所知,这可能是以一种比较笨拙的方式实现的,但由于一些复杂且违反直觉的原因是不可取的
尽管 x264 流具有帧速率,但帧速率更多的是容器级问题而不是编解码器问题。
在直通 VFR 编码中,将会有一个文本文件,详细说明哪些帧/时间的帧速率是多少;在对源进行编码时,tcfile-in 或 tcfile-out 之类的函数会将时间戳传递到编码,以映射速率位置并保持视频与源在主观上保持一致。
低帧率的想法合乎逻辑,但由于多种原因而行不通。尽管 x264 具有一些 VFR 感知功能,但我认为没有分析功能可以根据运动改变帧率以降低文件大小(类似于许多比特率控制)。
源也是一个问题:VFR 源默认会保留其帧可变性,但显然以可变比特率编码 CFR 文件(有时是个好主意,特别是当需要电视电影时)只会产生相同的 CFR。
这意味着你可能必须手动重写比特率(即慢速场景的时间戳混合到文件中),或者诉诸用于 avisynth 的帧抽取算法,如 dup、dedup 和 exactDedup。如果您的视频确实有极低的运动,一些帧(甚至一半?)将被丢弃。问题是这些算法并不先进,并且无法根据“真实”素材做出正确的选择,以确定哪些内容将有助于最佳编码。
此外,删除包含 I 帧和 B 帧等内容的帧会减少随时间推移可用的细节量,从而导致运动看起来“不规则”,并可能干扰其他基本视频参数并导致诸如混叠之类的伪影。
而且由于量化器的工作方式,x264 实际上会在这些低运动场景中进一步不成比例地降低比特率。除非您有相同图像的幻灯片,否则将会出现运动(如果只有颗粒和其他瑕疵),并且质量会有所下降,如果不对比特率进行大幅更改,则不会出现这种情况。
最后,没有太多选项可以实现您想要的效果的原因是 x264 非常擅长仅使用时间压缩(记录部分帧中的变化)来管理比特率。将帧率降低到 1/2 不会将文件大小减半;10% 可能是低运动或动画的实际增益。
简而言之,降低静态场景的比特率对文件大小影响不大,但会增加大量质量和同步问题,更不用说与视频编辑软件的不兼容。
如果你确实想尝试抽取器,你可以使用以下方法限制最大新帧速率:级别选项,每个都指定了最大分辨率和帧速率。不幸的是,使用配置文件,您可能必须以非常低的分辨率工作才能获得所需的帧速率。这又回到了手动编辑速率,要么完全编辑,要么纠正您认为过高的帧速率。无论哪种方式,如果在保存 tcfile 时在编码过程之后进行了更改,则需要进行调整以使声音与新的帧速率保持同步。
结论是,花时间优化多种比特率设置将在文件大小管理方面产生更大的收益,并提高视频质量,而不是为了获得一点点收益而造成麻烦。除非您的目标是广播或媒体标准,否则保留原始 FPS 可能是最好的主意。播放器经过精心设计,可以处理不同的比特率(与 NLE 不同)——并且视频中的帧越多,播放就越流畅,文件大小可能就越小,因为帧之间的运动变化更小。
这里收集了标准信息和论坛讨论的链接,希望对解决编码中这个令人困惑的方面有所帮助:
-fps 和 -r 开关
-x264 通用(tcfile、fps)
-时间码文件标准
-级别和配置文件
-简短、清晰的 CFR/VFR 设置摘要(“帧速率”部分)
答案3
完美解决方案:减少重复的非常相似的帧并以(峰值)可变帧速率保存输出
- 对于具有长静止场景的内容,删除重复的帧可以动态地降低帧速率,并且显著降低帧速率,从而实现比编解码器及其帧内压缩所能达到的更多的文件大小减小!
- 在我的例子中:
- 100% 原始夹层文件大小,60 FPS
- 60 FPS 恒定帧速率下 CR28 为 15%
- 60 FPS 峰值帧速率下 CR28 为 6%(几乎是 3 倍!)
有原件
ffmpeg -i screen-recording.mov -movflags faststart -c:v libx264 -vf mpdecimate -vsync vfr -r 120 -preset veryslow -crf 24 screen-recording-vfr.mp4
将已压缩的视频转码为动态帧速率,无需重新编码
ffmpeg -i video-export-old.mp4 -vf mpdecimate -vsync vfr video-export-mpdecimated-without-reencoding.mp4
详细
有原件
ffmpeg -i screen-recording.mov -movflags faststart -c:v libx264 -vf mpdecimate -vsync vfr -r 120 -preset veryslow -crf 24 "screen-recording-vfr.mp4"
-i video-mezzanine.mov Original or your high quality rendered export as the input file.
-movflags faststart Streaming ready by putting the moov atom to the file start.
-c:v libx264 H-264 codec
-vf mpdecimate Drop frames not differing greatly from previous frame to reduce frame rate.
-vsync vfr Output as variable frame rate (vfr)! Necessary sister option to 'mpdecimate'.
- To maintain the playback speed while benefitting from the file size reduction.
-r 30 If you specify -r then in this combo it serves as the peak framerate!
I recommend to omit this option:
- Then the peak framerate IS the peak/constant rate of the source.
- Which preserves dynamic scenes fully and compresses long still sequences.
- So the best of both aspects.
- State a peak FPS if loosing FPS in dynamic scenes
is acceptable for the reduction in file size.
-crf 24 - Constant Rate Factor (constant quality at variable bitrate)
-preset veryslow - Quality effort put into the encoding
screen-recording-vfr.mp4 - Output file
将已导出的视频转换为动态帧速率,无需重新编码
ffmpeg -i video-export-old.mp4 -vf mpdecimate -vsync vfr video-export-mpdecimated.mp4
这是一个无损操作。不会发生有损重新编码,只会重新打包/重新引用。
它会删除尽可能多的重复帧!
例子:
幻灯片仅显示 3 张静止图像,无过渡 * 每张持续 5 秒 * 50 FPS = 750 帧
ffmpeg
确实会将其减少到 3 帧,FPS 为 1/5 (=0.2)!已通过 mediainfo 确认!
分析与学习
- 具有长静态图像场景的视频的帧数和文件大小可以显著减少!
- 对于这两种情况
- 以相同的 CFR 从夹层文件进行编码可保持视觉质量
- 但是从恒定帧率到可变帧率,文件大小减少了 15% 到 6%。
- 不重新编码的情况下降低帧率对文件大小的减少影响不大,但仍然可以:
- 减少文件大小(从 15% 到 10%)
- 以相同的 CFR 从夹层文件进行编码可保持视觉质量
screen-recording.mov
- Frame rate mode: Variable
- Frame rate: 58.628 FPS
- Minimum frame rate: 30.000 FPS
- Maximum frame rate: 60.000 FPS
- Frame count: 732 100 %
- Size: 1675084 bytes 100 %
screen-recording CR24 fps 60.mp4
- Frame rate mode: Constant
- Frame rate: 60.000 FPS
- Frame count: 750 102 %
- Size: 255863 bytes 15 %
screen-recording CR24 mpdecimated vfr.mp4
- Frame rate mode: Variable
- Frame rate: 17.398 FPS
- Minimum frame rate: 1.132 FPS
- Maximum frame rate: 60.000 FPS
- Frame count: 214 29 %
- Size: 101860 bytes 6 %
screen-recording CR24 mpdecimated fps 30 max.mp4
- Frame rate mode: Variable
- Frame rate: 11.078 FPS
- Minimum frame rate: 1.154 FPS
- Maximum frame rate: 30.000 FPS
- Frame count: 137 17 %
- Size: 94382 bytes 5.6
screen-recording CR24 mpdecimated vfr without re-encoding faststart.mp4
- Frame rate mode: Variable
- Frame rate: 19.974 FPS
- Minimum frame rate: 1.132 FPS
- Maximum frame rate: 60.000 FPS
- Frame count: 247 33 %
- Size: 165 KB (164947 bytes) 10 %