(七)控制视频画面码率的方式背景,ffmpeg常用压制音视频参数总结
往期回顾。

这期我们来了解学习不同的控制码率方式以及ffmpeg用于压制的常用参数。像设置帧率、分辨率、音频采样率、声道等。另外,上期命令行压制出来的视频,通常输出的视频画面最终码率都还可以,和所设置的一般相差小于两百。但有时也会有偏差过大的情况,up这一般是比设置的多出大概几百,甚至上千。现在我们也来解决这个问题。
一、控制视频画面码率的方式背景
这块算是视频压制处理的背景知识,不只限于ffmpeg。
控制码率方式,是指通过什么方式来控制编码器的输出码率或解码器的输入码率,进而设置音视频的最终码率。这个最终码率比如指视频画面码率、视频声音码率、总比特率、pr里的“目标码率”……看我们具体操作的是什么。
这里介绍的是视频画面码率的控制方式。大体分为两类:固定码率(CBR,costant bit rate)、可变码率(VBR,variable bit rate)。
其中可变码率(VBR)可分为:二次编码(2pass)、固定质量(CRF,constant rate factor)、平均码率(ABR,average bit rate)。
我们接触比较多的通常就是这几个。up目前倾向于认为ffmpeg是默认以ABR方式控制码率的,不然如果是CBR的话那应该会精准很多(比如设定3000k压制出来是2994k左右这样)。
因此,顾名思义,CBR方式是通过固定之前说的输出或输入码率值来设置最终码率的,VBR方式就是说这个输出或输入的码率可以变动。2pass方式进行两次编码,第一次先预算全程的码率,第二次再运算输出,所以比较耗时。
但是实际上,无论哪一种方式,都不可能做到让码率全程丝毫不变。就CBR来说,对于我们设置的码率数值,实际压制运行过程中CBR方式是将码率限制在这个数值附近的一个小范围内波动。ABR通俗来说可看做是VBR与CBR的折中方案,它的“波动”比CBR要大一些。而至于2pass和CRF,“波动”就更大了。
这个“波动”意味着什么呢?对视频而言,画面里的场景、人物等变化越快速繁杂,这个地方就越需要更多的码率。“波动”越大,说明这种控制码率方式对码率更加的“自由”:哪里需要码率,码率就能去哪个地方。这样的话视频的实际质量也会越好。CRF方式以质量为首,在所设定的数值上不用担心哪个地方码率“不够用”,缺点是CRF不确定最终码率和文件大小。
所以,四种方式对“波动”从大到小的排序为CRF>2pass>ABR>CBR。若考虑实际质量优先的话,我们首选CRF,如果压制需求还有码率限制,就选择2pass。
不过,“波动”范围大了也会有问题。无论是本地还是网络,“波动”太大的话可能会因为播放器解码不过来,网络加载不过来而发生播放卡顿、看一会缓冲一会的现象。(反之不一定,也可能是其它的编码问题,网络状况或者串流协议问题等)理解起来就是,一个视频不同的地方,若码率相差太过悬殊,有些比如1234k,有些地方达到23456k,那就“波动”过大,播放的时候就“吃力”了。
现在大多是通过网络来传输、观看视频听音乐,如果能做到“波动”比较小,那对于相同或者一般般的网速来说就更容易缓冲播放。(这点也还涉及到串流协议等问题)对CBR来说,它是要想方设法地减小“波动”,有些码率太高的地方就直接砍掉压掉,而码率较低的地方就“灌水”填充进去。
总而言之,CBR方式最利于传输视频,但最不利于本地存储,也最损失实际质量。CRF方式则最利于本地存储,最不利于传输,最大程度保存质量。如果以质量优先兼顾传输推荐考虑2pass,以传输优先兼顾质量则考虑ABR。
二、常用压制音视频参数
“-r”,“frame,帧率”的意思。非常好理解,“-r 25”就是指设置视频帧率为25。
“-s”,resolution,分辨率。相同地,“-s 1920x1080”指设置视频分辨率为1920x1080,即1080p(这里ffmpeg默认逐行扫描,基本都不用考虑这个问题)。像“-s 1280*720”这样也是可以的。
“-vol”,volume,音量。“-vol 256”表示原音量,“-vol 512”表示原来音量的两倍,以此类推。(这个参数比较过时了,但依然很好用)
“-ab”,audio bitrate,音频比特率。例如“-ab 320k”表示设置音频的比特率为320k。对视频里的音频设置也是可以的。
“-ar”,audio sampling rate,音频采样率。如“-ar 44100”。(这个通常不用设置,ffmpeg以原来的数据直接默认)
“-ac”,audio channels,音频声道。如“-ac 2”表示双声道,“-ac 1”表示单声道。(这个通常也不用管)
三、控制视频画面码率的参数
“-pass 2”,使用“二次编码”方式。同理,“-pass 1”即为一次编码,范围是1~3。注意会在所输出目录生成如下两个文件:

注意“-pass 1”的使用和平常一样,但使用“-pass 2”或“-pass 3”要先运行一遍“-pass 1”,再来运行。这里运行“-pass 1”的时候因为这时只是预算视频画面数据,可以使用“-an”不对音频操作,最后以“NUL”表示不输出视频文件,之后“-pass 2”再来输出。例如:
ffmpeg -i .\input.mp4 -b:v 2000k -c:v libx264 -pass 1 -an -f mp4 NUL
ffmpeg -i .\input.mp4 -b:v 2000k -c:v libx264 -c:a copy -pass 2 .\output.mp4
“-crf”,使用“固定质量”方式。例如“-crf 20”,一般选择16~25,范围0~51,数值越小质量越高。简单理解为0是无损,51是全损,在这之间划分了52个质量等级。
“-preset”,preset,预设,相当于预设好的一些用时、质量不同的压制方案。默认“-preset medium”。从快到慢有ultrafast,superfast,veryfast,faster,fast,medium,slow,slower,veryslow,placebo。一般看情况用faster~slower之间这些就可以。
“-tune”,tune,调谐。根据输入文件的“特性”所采取的一些压制方案。如“-tune film”。有以下这些:film(一般文件),animation(动画),grain(老视频颗粒噪音),still image(图片幻灯片),fast decode(解码快),zeolatency(网络视频、编码快)。
如果出现了最终码率与“-b”设置的偏差过大(即“码率溢出”)的情况可考虑如下参数。up目前也没很明白,就只给出用法例子不作说明了。
这里有一个“缓冲区”的概念。简单理解就是,缓冲区像一个池子,码率就像水,把水一直放进池子里装着给播放器解码。每次解码用的水都不同,就是指之前说的不同地方的码率有高有低。我们要做的是想让池子里的水一直保持在一个范围内波动,这样便可减小原来的“波动”也防止码率溢出。
“-bufsize”,设定码率控制缓冲区大小,让整体的码率更趋近于希望的值,一般配合“-b:v”使用,减少“波动”。例如“-b:v 2000k -bufsize 2500k”。
“-maxrate”,设定缓冲区最大填入速度。如“-b:v 3000k -maxrate 2000k”。
“-minrate”,设定缓冲区最小填入速度。如“-b:v 3000k -minrate 1000k”。
更进一步,这三个参数需要配合公式计算使用。而且,缓冲区也可能存在溢出等情况
(具体参考文章https://blog.csdn.net/soulmate_scut/article/details/82985365)
还有一个感觉用得很少的参数“-fs”,限制输出文件的大小。如“-fs 120.6M”(注意是大写M)表示限制输出文件的大小为120.6MB(但实际上一般输出文件最终会略大于所限制的这个数值),注意这并不是将整个文件压制到所限制的大小的意思,“-fs”是让ffmpeg运行处理到所限定的文件大小时就自动停止结束。像秒表一样,“-fs”只是设定了一个“”文件大小size计时“,其它另外的处理得看其它参数的设置。
最后补充三个有时能带来执行方便的参数:
“-y”,若输出目录已存在同名同容器格式的文件,直接输出当前文件将其覆盖而不再询问。
“-n”, 不要覆盖输出文件,如果已经存在同名同容器格式的文件,立即结束运行。与“-y”相反。
“-hide_banner”,隐藏版本号及一些描述信息。如下两图:


至此,《通俗易懂的ffmpeg系列教程》的启蒙、转码、简单剪辑、压制篇章就完结啦!以后up会更新一些ffmpeg非常实用的命令行技巧,当然还有很多更深奥但也是实用的东西x~希望能得到大家继续的关注支持啦~
感谢你观看到这里。