![使用 ffmpeg 进行视频压缩 - 恒定质量](https://linux22.com/image/1369374/%E4%BD%BF%E7%94%A8%20ffmpeg%20%E8%BF%9B%E8%A1%8C%E8%A7%86%E9%A2%91%E5%8E%8B%E7%BC%A9%20-%20%E6%81%92%E5%AE%9A%E8%B4%A8%E9%87%8F.png)
我正在尝试使用 ffmpeg 以不同的比特率压缩 10 秒的视频。我的目标是以不同的质量(从非常低到非常高)获得相同的视频。我不想触及音频部分,我使用 H264 作为视频编解码器。我使用以下 CLI:
ffmpeg -i input.mkv -c:v libx264 -b:v $j'k' -c:a copy output.mkv
其中 $j 范围从 150 到 4000。
我的问题是,我压缩了 10 秒的视频,但质量在整个过程中并不稳定。下面是一个例子:比特率非常低($j = 150),在开始时(0 到 3 秒之间),视频质量很差,但在结束时(8 到 10 秒之间),质量正常!此外,在观看视频时,可以看到质量随着时间的推移而提高。有人能解释一下这种现象吗?如何获得恒定的质量?
谢谢'
答案1
正如@LordNeckbeard 已经指出的那样,恒定比特率并不等同于恒定质量。事实上,情况恰恰相反。视频序列的某些部分比其他部分更容易编码(更容易,因为需要的比特更少),而其他部分则不然。如果你把所有的比特都花在容易的部分上,那么在困难的部分你就会缺乏比特。
这就是恒定质量发挥作用的地方。在 x264 中,恒定利率因子,它确实做到了这一点。如果您想了解更多背景信息,我建议您阅读链接的文章。基本上,CRF 的范围从 0(无损,最佳)到 51(最差)。±6 的步长大致相当于比特率的两倍或一半。
因此,要调整您的脚本,只需执行以下操作:
for i in $(seq 0 5 51); do
ffmpeg -i input.mkv -c:v libx264 -crf $i -c:a copy output-$i.mkv
done
除非我弄错了,否则该尺度本身在质量方面接近对数,因此您可以根据该尺度而不是呼叫来计算您的步数seq
。
当比特率非常低($j = 150)时,在开始时(0 到 3 秒之间),视频质量非常差,但在结束时(8 到 10 秒之间),质量就很好了!此外,在观看视频时,可以看到质量随着时间的推移而提高。有人能解释一下这种现象吗?
对于编码器来说,保持恒定比特率并非易事。你给它一个特定的值,例如告诉它“给我每秒 150 kBit”,但编码器甚至不知道下一帧要编码什么。
那么,它应该在这一帧上花费多少?下一帧又要花费多少?有些帧(如我上面提到的)很容易编码,只需要几千比特,而其他帧可能需要更多。但编码器实际上只能查看过去编码的内容,以便为未来的图片进行扩展。还需要考虑不同的图片类型。
从算法上讲,实现恒定比特率非常困难,而且这也是 x264 提供的速率控制模式中最糟糕的。特别是对于短片,由于编码器在不进行 2 遍编码的情况下不知道可以期待什么,您可能会注意到您描述的方式:质量在十秒钟内发生了巨大变化。但无论如何,150 kBit/s 对于尺寸相当不错的视频来说确实不够。