常用编码器与参数

警告

依赖于 FFmpeg 的默认操作是不可取的,因为我们不知道 FFmpeg 会在哪一个版本发布时更改其默认操作。除非不在意任何编码细节,否则请显式地指明编码器及其参数。这也是需要了解编码器参数的原因。

本章介绍一些常用编码器的参数使用方法。绝大部分的内容来自于 FFmpeg 的 trac 百科。

libx264(H.264 视频)

H.264 在很长的一段时间内都是最广泛使用的视频编码方式,其编码器 libx264(参考 libx264_002c-libx264rgb)很可能是 FFmpeg 用户第一个接触的视频编码器。

在输出 mp4 格式的文件时,如果需要对视频流编码但用户未指定编码器,FFmpeg 将自动调用 libx264 并以其默认参数进行编码。

# 以下命令等于 ffmpeg -i input.mkv -c:v libx264 output.mp4
ffmpeg -i input.mkv output.mp4

关于 libx264 的压制与码率详细使用,我们在前文 压制与码率 一节已有所提及。为了方便起见,这里对前文稍作小结,并加入了。

  • 恒定率系数(CRF):crf 越小,画面质量越好,但文件体积越大。

    • 系数 -crf:对于常见的 8 bit H.264 视频, -crf 参数可以从 0(无损)到 51(最差压缩)取值,而默认值是 23。一般地,我们只选择 17~28 之间的数值:从视觉观感上,17 已经很接近无压缩的结果,更小的 crf 值徒增文件体积罢了。

      • 对于 10 bit H.264 视频, -crf 参数的取值是 0~63。

    • 预案 -preset:指导视频压制的质量。越慢的预案,压缩越好,即输出同等质量的视频所需的文件体积越小。预案从快到慢包括:ultrafast, superfast, veryfast, faster, fast, medium(默认), slow, slower, veryslow。

      • 从输出质量上讲,只建议使用 medium 或更慢的预案,一般以使用 medium 或 slow 最为常见。例外的情形是指定了无损(CRF=0)的情形,此时可以选用 ultrafast。

    • 风格 -tune:告知输入视频的风格。风格包括:

      • animation:动画。提升去块(deblocking)强度与参考帧数量。

      • fastdecode:快速解码。禁用滤镜来加快解码。

      • film:电影。降低去块强度。

      • grain:颗粒。保留旧电影的颗粒感。

      • stillimage:静止图像。适用于相片幻灯片或类似主题的内容。

      • zerolatency:零延迟。适用于快速编码,或者低延迟流媒体内容。

    一个 CRF 的例子:

    ffmpeg -i video.mp4 -c:v libx264 -preset slow -tune film -crf 20 -c:a copy out.mp4
    
  • 定限码率压制:适用于强制要求码率的场合,比如直播。请参考 定限码率压制 一节的内容。

  • 二压(2Pass):适用于强制要求文件大小的场合。请参考 二压(2Pass) 一节的内容。

libx265(H.265/HEVC 视频)

H.265 的许多参数与 H.264 相同(但取值含义可能不同),只是使用 libx265 编码器代替 libx264。

  • 恒定率系数(CRF):crf 越小,画面质量越好,但文件体积越大。

    • H.265 的默认 CRF 取值是 28,这不同于 H.264 的默认 CRF 取值 23;它们两者对应的视觉画面质量相同。

    • H.265 的视觉上的无损 CRF 值(从经验上)大约在 20~22,这不同于 H.264 中的 17。

    • H.265 的取值范围始终为 0(无损)到 51(最差压缩),这不同于 H.264 的 CRF 取值范围(8bit 0~51; 10bit 0~63)。

      libx264 与 libx265 的 CRF 取值无法对应

      libx264 与 libx265 的 CRF 取值没有一一对应的公式。除了上文所述的无损参数均为 CRF=0、libx264 CRF=23 对应 libx265 CRF=28,其余 CRF 值并不存在对应关系。

    • 预案 -preset:指导视频压制的质量。其取值与 libx264 相同,默认为 medium。

      • 与 libx264 类似,我们建议使用 medium/slow 或更慢的预案。例外的情形是指定了无损(CRF=0)的情形,此时可以选用 ultrafast。

      • 较慢的预案在同等的 CRF 值上有更好的表现。建议在选用更快速的预案时,适当降低 CRF 值以保持相近的质量。

    • 风格 -tune:告知输入视频的风格。libx265 支持的风格不如 libx264 多,只包括:

      • fastdecode:快速解码。禁用滤镜来加快解码。

      • zerolatency:零延迟。适用于快速编码,或者低延迟流媒体内容。

  • 定限码率压制:用法与 libx264 类似,适用于强制要求码率的场合,比如直播。请参考 定限码率压制 一节的内容。

  • 二压(2Pass):用法与 libx264 类似,适用于强制要求文件大小的场合。但请注意,编码器 libx265 需要额外在两步中指定 -x265-params 参数。具体的用法,请参考 二压(2Pass) 一节的内容。


如果要以 10 bit 色深编码 H.265 视频,使用 -x265-params 下的 profile 参数。例如:

ffmpeg -i video.mp4 -c:v libx265 -crf 21 -preset faster -tune fastdecode -x265-params profile=main10 -c:a aac -b:a 192k out.mp4
  • 如果输入视频是 8 bit 的,那么需要使用 -pix_fmt 参数将其转为 10 bit:

    ... -i video.mp4 -pix_fmt yuv420p10le -c:v libx265 ...
    

libsvtav1(AV1 视频)

备注

libsvtav1 编码器在 FFmpeg 5.1 版本后加入到了官方编译版本中。我推荐使用它,而不是较老的 libaom 编码器。本节也只介绍 libsvtav1 的使用。

重要

libsvtav1 是一个较新的编码器,其参数可能发生变化,因此本小节中的内容(基于 FFmpeg 7.0)可能与您所安装版本的不同。具体请参考所安装的 FFmpeg 的命令行帮助:

ffmpeg -h encoder=libsvtav1

也可以参考 SVT-AV1 官方针对 FFmpeg 撰写的 使用指南

AV1 可以视作是 H.265 的继任者,不仅提供了更好的压缩率,在使用权利上的约束也更少。当然,转码的开销也更大;用户需要较新的硬件支持,否则转码速度将会极慢。

libsvtav1 编码器使用的许多参数都类似 libx264/libx265,常用的有:

  • 恒定率系数(CRF):crf 越小,画面质量越好,但文件体积越大。

    • AV1 的取值范围始终为 1(最好压缩)到 63(最差压缩),这不同于 H.264 的 CRF 取值范围(8bit 0~51; 10bit 0~63)。AV1 中的 CRF 默认值为 35。

  • 预案 -preset:指导视频压制的质量。数字越大,编码越快,同时质量越差。

    • 取值范围为 -1 到 13(默认为 -1)。

    • SVT-AV1 在 官方问答 中建议一般用户使用 预案 4-6 作为一般选择,以平衡存储效率与压制时间。预案 1-3 压缩质量上佳,但是编码极度缓慢;预案 7-12 用于希望进行快速编码的场合;预案 13 通常只用于开发者测试。

  • 关键帧间隔帧数量 -g:这实际上是 FFmpeg 的通用参数。一般根据视频帧率,取 5 到 10 秒(但不应超过 300)。一个较通用的 g 值是 240,它对应 24 帧视频的 10 秒,或者 30 帧视频的 8 秒。该参数也可以在编码器参数中用 keyint 直接指定时长。

  • 常用编码器参数 -svtav1-params:使用键等于值( key=value )的格式书写,并用冒号分隔。

    • 主观质量模式 tune:采用值 tune=0 可以切换到主观质量模式(VQ),这将稍微锐化图像并提供更好的“心理视觉效果”。默认值为 1,即峰值信噪比(PSNR)模式。

    • 关键帧间隔时长 keyint:一般取 5-10 秒,请注意带单位 s,例如 keyint=8s 。默认值为 -2(约 5 秒)。

    • 快速解码等级 fast-decode:取值从 0(关闭)到 2(最高)。默认值 0。尽管该参数可以用于主观质量模式,但它是在 tune=1 (默认)模式下开发测试的,因此不推荐与主观质量模式共用。

      警告

      我很少用到 fast-decode 参数,也不推荐在没有 AV1 解码能力的硬件上播放 AV1 编码的视频。因为 AV1 解码的开销较大,即使使用了快速解码模式,在旧硬件上播放也非常容易卡顿。这时候应该放弃文件体积优化,使用硬件支持较好的方式(H.265 甚至 H.264)进行编码,优先保证播放的流畅性。

    • 去颗粒等级 file-grain:取值从 0(关闭)到 50(最高)。默认值 0。

      去颗粒等级并不是越高越好,过高可能会损害原有图像质量。根据官方问答,这里提供以下建议:

      • 如果原视频具有通常级别的颗粒数量,建议使用 8 左右的数值;如果颗粒比较明显,考虑使用 10-15 之间的数值。

      • 如果原视频是平面动画类,建议使用较低的去颗粒等级(4 左右),或者不使用。

      • 如果原视频没有颗粒/热噪,建议不使用该参数,以提高编码速度与避免质量损失。

官方同样在问答中建议总是使用 10 bit 编码输出;即使源是 8 bit 视频,也可以通过 -pix_fmt yuv420p10le 参数来强制转 10 bit。这样能以较小的开销(约 5% 的文件体积增长)降低运算时的损失。

下面给出一个针对 8 bit 视频的 AV1 转码示例,主要参数释义如下:

  • 预案 -preset 5 ,采用了官方建议的一般用户预案 4-6 的中间数。

  • CRF 参数 32 是官方示例中的值

  • 关键帧间隔参数 -g 240 。对 30 帧视频而言,即 8 秒一个关键帧。

  • 色深度 -pix_fmt yuv420p10le ,强制指定输出编码为 10 bit;如果原视频是 10 bit,则可省略该项。

  • 在编码器参数中,此处使用了主观质量模式与 8 级去颗粒。

ffmpeg -i video.mp4 -c:v libsvtav1 -preset 5 -crf 32 -g 240 -pix_fmt yuv420p10le -svtav1-params tune=0:film-grain=8 -c:a copy out.mp4

libmp3lame(MP3 音频)

MP3 曾经是最为流行的压缩音乐格式。FFmpeg 通过 libmp3lame 编码器对 MP3 编码提供支持,一般有可变比特率、固定比特率、平均比特率三种质量控制方式。

可变比特率(VBR)

一般地,推荐利用可变比特率(VBR)来编码 MP3 音频:

ffmpeg -i input.wav -c:a libmp3lame -q:a 2 output.mp3

其中,质量参数 -q:a (或者其全称 -qscale:a)用于控制 MP3 品质。编码器 libmp3lame 支持 0~9 的质量参数,其中 0 表示最高质量(最高比特率,245 kbps 左右),而默认值是 4。一般认为 0~3 的取值可以达到令人满意的质量。

FFmpeg 比特率参数与实际比特率范围(kbps)有如下对应关系:

FFmpeg 比特率参数与实际比特率范围对照表

参数

平均比特率

比特率范围

-b:a 320k*

320

320 (CBR)

-q:a 0

245

220 ~ 260

-q:a 1

225

190 ~ 250

-q:a 2

190

170 ~ 210

-q:a 3

175

150 ~ 195

-q:a 4

165

140 ~ 185

-q:a 5

130

120 ~ 150

-q:a 6

115

100 ~ 130

-q:a 7

100

80 ~ 120

-q:a 8

85

70 ~ 105

-q:a 9

65

45 ~ 85

* 此为 MP3 所支持的最高码率,但在实际应用中并不推荐。详情请参考下文中关于固定比特率(CBR)部分的内容。

固定比特率(CBR)

除了可变比特率,在网络上分享的 MP3 文件也常常采用固定比特率(CBR)编码,如 128, 192, 256 kbps。编码器 libmp3lame 通过 -b:a 参数支持一系列固定比特率,分别是 8, 16, 24, 32, 40, 48, 64, 80, 96, 112, 128, 160, 192, 224, 256, 以及 320 kbps。

警告

一般认为在 MP3(或者其他压缩格式上)追求高码率(如 320 kbps) 是没有意义的,因为 VBR 0~3 的质量对压缩格式已经足够好。毕竟无论如何,MP3 都是有损压缩;想要更高的质量,建议转向 FLAC 等无损格式。

下例将音频以 192 kbps 的固定码率输出为 MP3(不要忘记码率数字后面的字母 "k"):

ffmpeg -i input.wav -c:a libmp3lame -b:a 192k output.mp3

平均比特率(ABR)

平均比特率(ABR)介于固定与可变之间,可以向参数 -abr 赋值 1 来启用。除此之外,libmp3lame 编码器此时仍需要 -b:a 的码率参数作为指导:

ffmpeg -i input.wav -c:a libmp3lame -abr 1 -b:a 192k output.mp3

aac(AAC 音频)

AAC 是另一种常见的有损音频编码。AAC 普遍在 MP4 视频容器中被使用,它也常用作独立的音频 m4a 文件。

FFmpeg 原生支持 aac 编码器,声称是仅次于 libfdk_aac 的 AAC 编码器。官方提供的编译版本不使用 libfdk_aac 编码器,用户使用则需要重新编译 FFmpeg 。

建议在原生的 FFmpeg aac 编码器上使用固定比特率(CBR)参数 -b:a

ffmpeg -i input.wav -c:a aac -b:a 192k output.m4a