FFmpeg全名是Fast Forward MPEG(Moving Picture Experts Group),为开源的影音多媒体处理框架,可以进行影音的解码、编码、编码转换、混合、抽取、串流和滤镜,无论影音格式是从哪个地方出来的,从过去到现在的影音格式它几乎都能够支持。当然,它也可以利用x265这款高品质的开源H.265编码器来进行H.265编码。

x265虽然本身有提供指令工具,但基于它无法同时处理音频以及文件容器的原因,我们很少会直接使用它,而是会通过其它前端的接口来使用它的libx265函数库。一般来说,使用x265进行视频编码会选择使用--crf参数来设置CRF(Constant Rate Factor)控制视频画质,数值愈低画质愈高(比特率相对愈高)。此外,x265指令工具还有提供一个--preset参数,它可以帮助我们快速设置x265编码时所用的众多参数。依照编码速度的不同,preset由快到慢可以分为:ultrafastsuperfastveryfastfasterfastmediumslowslowerveryslowplacebo这9个等级,原则上愈慢则会有更好的压缩效果或是画质。

使用FFmpeg指令工具来操作x265编码器时,x265--crf参数会对应到FFmpeg的-crf参数,数值范围为0 ~ 51,默认值为28,20左右即达到视觉无损;--preset参数会对应到FFmpeg的-preset参数,默认值为medium

通过FFmpeg输出视觉无损的H.265/HEVC视频的指令如下:

ffmpeg -i 输入的影音文件路径 -vcodec libx265 -crf 18 输出的影音文件路径

通过FFmpeg输出标准画质的H.265/HEVC视频的指令如下:

ffmpeg -i 输入的影音文件路径 -vcodec libx265 输出的影音文件路径

使用最高的压缩效果来输出视觉无损的H.265/HEVC视频,指令如下:

ffmpeg -i 输入的影音文件路径 -vcodec libx265 -crf 20 -preset placebo 输出的影音文件路径

使用最低的压缩率来输出视觉无损的H.265/HEVC视频(通常作为输出正式结果前的测试),指令如下:

ffmpeg -i 输入的影音文件路径 -vcodec libx265 -crf 20 -preset ultrafast 输出的影音文件路径

不过实际上,即便用CRF编码模式,-preset参数还是会影响到输出画质的。可参考这篇文章来比较看看。

4:2:0/4:2:2/4:4:4和8-bit/10-bit视频编码

缺省情况下,FFmpeg使用x265来编码H.265/HEVC时,会根据视频输入源来决定输出的色彩采样方式和色彩深度。常见的色彩采样方式为4:2:0(支持硬件解码),特殊情况下才会去用到4:2:2或是4:4:4。色彩采样对于画面的呈现差异并不明显,但对于后制宽容度的影响比较大。而色彩深度则影响到视频的颜色表现范围,这个要看视频来源,如果视频原本就是用10-bit深度的设备进行录制或是制作的话,那么降转成8-bit时就会出现色班、色块等色阶不连续的情况。

FFmpeg指令工具可以利用-pix_fmt参数来设置输出视频的像素格式来决定其色彩采样方式和像素格式,搭配libx265编码时,会自动选择适当的H.265/HEVC Profile来使用。

像素格式yuv420p,代表要使用8-bit 4:2:0进行编码;yuv422p,代表要使用8-bit 4:2:2进行编码;yuv444p,代表要使用8-bit 4:4:4进行编码;yuv420p10le,代表要使用10-bit 4:2:0进行编码;yuv422p10le,代表要使用10-bit 4:2:2进行编码;yuv444p10le,代表要使用10-bit 4:4:4进行编码。

通过FFmpeg输出视觉无损的10-bit H.265/HEVC视频的指令如下:

ffmpeg -i 输入的影音文件路径 -vcodec libx265 -crf 20 -pix_fmt yuv420p10le 输出的影音文件路径

CVBR(约束的变动比特率)

CRF是以画质为基准的视频编码方式,所以其编码结果会根据该片段内的复杂程度来决定其所使用的比特率,也就是变动比特率(VBR)。因此,对于复杂的运动场景,比特率被拉得很高,如果这个视频是用在网络串流的话,用户就容易发生卡顿的情形。CVBR编码模式是以VBR编码模式为基础,再增加比特率最大值(也可加上最小值)的限制,若是x265在编码时发现该片段需要比设置的比特率最大值还要更大的比特率才有办法处理的话,就会自动调高CRF(降低画质)来进行编码。

替FFmpeg加上-maxrate参数传入要设置的比特率最大值,另外还要传入-bufsize参数来设置解码器用的缓冲空间。-bufsize参数的值并没有固定,我们可以先把它设为跟-maxrate参数一样或是一半的值,再慢慢往上加,直到最终的输出比特率接近我们设置的比特率最大值。如果不设置-bufsize参数的话,输出的比特率会偏低;如果有适当地设置-bufsize参数,我们就可以利用以下公式来预估编码后的视频大小:

约束的变动比特率(Kbps,Kb/s) x 时间(s,秒)/8(b/B)=视频的大小(KB)

为什么要有-bufsize参数?当我们在网络串流视频的时候,视频数据并不是被我们接收到之后就立刻解码播放到屏幕上,而是会先存入「缓冲空间」。假设我们的网络带宽有1Mbps,经过N秒就有N Mb的数据进入缓冲空间中。由于视频比特率是变动的,可能第1秒的数据只占了0.5 Mb,而第2秒的数据却有1.5 Mb,我们的播放器再播放第1秒视频内容的时候,就会取得第2秒一部份的视频内容,放在缓冲空间中。若缓冲空间至少有0.5 Mb,即便我们的网络带宽不足1.5Mbps,这个视频也可以顺畅播放。-maxrate参数的值其实也代表着用户最低限度的网络带宽,搭配-bufsize参数来使用时,设置愈高的缓冲空间,可以允许视频的某些片段使用比-maxrate设置的最大比特率还要更大的比特率来处理复杂的场景。

通过FFmpeg输出视觉无损的CVBR 2Mbps H.265/HEVC视频的指令如下:

ffmpeg -i 输入的影音文件路径 -vcodec libx265 -crf 20 -maxrate 2M -bufsize 16M 输出的影音文件路径

二次编码(2-pass)

如果是为了要输出固定大小的视频而使用CVBR编码模式的话,可能就得重复转好几次档,找出适当的-bufsize参数的值。其实有个更好的方式只要固定编码两次就好了,第一次编码的目的是收集编码视频来源时所得到的信息(缺省会在工作目录中被存成x265_2pass.logx265_2pass.log.cutree文件),第二次是利用已收集到的信息和相同的视频来源编码出比特率有被精确控制过的视频。

利用FFmpeg提供的-b:v(-vb)参数,可以直接设置视频的平均比特率。再加上-x265-params pass=1参数表示要进行第一次编码;-x265-params pass=2参数表示要进行第二次编码。

例如要使用最高的压缩效果输出平均比特率为2Mbps的H.265/HEVC视频,第一次编码的指令如下:

ffmpeg -i 输入的影音文件路径 -vcodec libx265 -b:v 2M -preset placebo -x265-params pass=1 -an -sn -y -f mp4 /dev/null

由于第一次编码输出的视频文件,其比特率可能会和我们从参数设置的比特率有所差距,所以不让它保存成文件。当然,您也可以选择存下来,因为说不定它就正好是我们要的比特率,这样也不需要继续接下来的第二次编码了。另外,还用了-an-sn参数使FFmpeg不要去处理音轨和字幕轨;-y参数使FFmpeg不询问是否覆盖文件。上面的指令是给Unix-like的操作系统用的,如果是Windows的话要使用下面这个指令:

ffmpeg -i 输入的影音文件路径 -vcodec libx265 -b:v 2M -preset placebo -x265-params pass=1 -an -sn -y -f mp4 NUL

第二次编码的指令如下:

ffmpeg -i 输入的影音文件路径 -vcodec libx265 -b:v 2M -preset placebo -x265-params pass=2 输出的影音文件路径

无损压缩

H.265支持无损压缩,加上-x265-params lossless=1参数就好了,不要设置-crf-b:v参数。

使用最高的压缩效果来输出无损画质的H.265/HEVC视频,指令如下:

ffmpeg -i 输入的影音文件路径 -vcodec libx265 -x265-params lossless=1 -preset placebo 输出的影音文件路径

Tune

针对不同地影像来源类型或是输出目的,x265还可以加上--tune参数控制一些编码细项来优化结果。FFmpeg对应的参数为-tune-tune可以使用的值有以下几种:

  • animation:2D动画。(有大范围同色色块,且上、下张变化不大的影像)
  • grain:老电影。(有颗粒感的影像)
  • fastdecode:输出适合在低端设备播放的视频。
  • zerolatency:输出适合低延迟串流的视频。
  • psnrssim:针对PSNR或是SSIM进行优化,对视觉品质可能没有实质意义上的帮助。

原文地址:如何用FFmpeg将影像转成H.265/HEVC格式?

最后修改:2022 年 12 月 04 日 12 : 35 AM
如果觉得我的文章对你有用,无需赞赏用心感谢!