ffmpeg
控制视频画面码率的方式背景
这块算是视频压制处理的背景知识 , 不只限于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"再来输出。例如:
| |
| |
"-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" , 隐藏版本号及一些描述信息。
压缩视频从而在微信不被压缩的命令
要点就是减少码率, 然后旋转为竖屏
| |
直接旋转元数据,不修改内容的,很快 (不改变码率)(好像不起作用。。。依然会被微信识别成横屏)
| |