🎬 第十一章 体验FFmpeg 5.0
📄 一句话概括

5.0 是 2022-01-17 发布的大版本,代号 Lorentz,动的是库的接口,不是命令的写法。 命令行用户唯一会碰到的变化,是 AAC 编码器的默认参数被调过。

📝 本节和前面几节的关系

前面十章用的都是「命令怎么写」,这一章换成「装的到底是哪个版本」。 先搞清楚 5.0 改了什么、没改什么,后面四节「用 5.0 实现 XX」才不会白读。

一、这一次大版本,动的是地基

FFmpeg 5.0 发布于 2022 年 1 月 17 日,代号 Lorentz。 官方公告里那句「这次大版本做了很大努力,把旧的编码/解码 API 拿掉、 换成一套新的 N:M 接口」,就是这一版的主线。

说白了:以前音频一套接口、视频一套接口,两边写法还不一样; 5.0 把它们合并成一套,同时把攒了十来年、标了「废弃」却一直没删的接口一次删干净。 官方说法是这批删除有八十多个提交,动静是 FFmpeg 历史上最大的一次。

另外三条主线:libavresample 整个库被删除(重采样统一走 libswresample)、 libswscale 换了一套更容易用的接口、Vulkan 那套代码大改并接进了 libplacebo。 再加上杜比视界的支持(含色调映射和转封装),5.0 的「大版本」名副其实。

但这些都发生在库那一侧。 一个只敲 ffmpeg -i ... -c:v libx264 ... 的人,升级到 5.0 之后会发现命令一个字都不用改。 这不是巧合,是 FFmpeg 有意维持的约定: 命令行是稳定层,库接口才是会动的那一层。

二、三个版本号,三套算法

「我装的是哪个版本」这个问题,答案不止一个。 本机实测能一次问出六个数:

看到的是 本机的值 它到底是什么


PyAV 18.1.0 Python 绑定自己的版本 libavcodec 62.28.102 真正干编解码的库 libavformat 62.12.102 管容器读写 libavfilter 11.14.102 管滤镜 libavutil 60.26.102 公共设施,时间基就在这儿 libswscale 9.5.102 管像素格式转换

这些数字里藏着好几套各算各的大版本: 62 是 libavcodec 的 ABI 大版本,11 是 libavfilter 的,60 又是 libavutil 的。 而「FFmpeg 5.0」这个发行版本号,在这六个数里一个都找不到。

所以「FFmpeg 5.0」和「libavcodec 62」是两种完全不同的编号: 前者是给整套源码打的标签,后者是某个动态库的 soname 大版本。 两者之间只有一张对照表,没有算术关系。 想知道手上这套是哪个发行版,只能查表,或者看 ffmpeg -version 的第一行。

按 ABI 大版本对照,本机这一套(libavcodec 62)属于 FFmpeg 8.0 系列, 比这一章要装的 5.0 还高三个大版本。 这件事本身很有用:后面几节写的都是「5.0 上的命令」, 而它们在本机这套 8.0 上照样跑通—— 跨三个大版本命令还能用,正好证明命令行这一层是稳的。

三、变化清单,按「影响谁」重排

官方公告是按模块列的,读起来累。换成「影响谁」就好懂了:

5.0 的变化 影响谁


编解码 API 统一成一套 写 C 的人,跟命令行无关 旧解码 API 全部移除 还在用 2013 年接口的程序 libavresample 整库删掉 自己调重采样的项目 swscale 换成新 API 写 C 的人 Vulkan 大改、接入 libplacebo 想要 GPU 滤镜的人 支持杜比视界 做 HDR 片源与转封装的人 AAC 编码器默认参数调整 命令行用户唯一会碰到的

最后一行是唯一会落到命令行用户头上的: 同一条不写 -b:a 的命令,4.x 和 5.0 出来的音频码率可能不一样。 这一点 11.2 会用实测数据说清楚。

至于新滤镜,5.0 一口气加了二十来个(speechnorm、varblur、huesaturation、 morpho、segment 等等),11.4 会逐个点名—— 但重点是它们「在不在」,而不是「5.0 才第一次有」。

四、为什么书里四节命令一模一样

翻开这一章的目录会发现:11.2 转码、11.3 跑马灯、11.4 特效、11.5 直播, 四节的标题就是前面几章标题的重复,只是前面多了「使用 FFmpeg 5.0」几个字。

这不是作者偷懒。 因为这一章真正要讲的是「换版本之后有什么不一样」, 而答案是:命令层面几乎没有不一样。 所以这四节的作用是复核—— 把第五章的转码、第六章的跑马灯、第七章的特效、第八章的直播,在 5.0 上再走一遍, 确认「换版本不影响我手上这套命令」。

换个角度说,这一章真正在教的是「怎么读一个大版本的公告」: 先分清它动的是库还是命令行,再看自己会不会碰到—— 绝大多数人只会碰到「某个滤镜忽然没了」或者「默认码率变了」这两类。

五、读公告的两个入口

官网的公告页把内容分两处放,各看各的:

看哪里 有什么 谁该看


Changelog 新增的滤镜、编码器、格式 命令行用户 APIchanges 库接口的增删改 写 C/写绑定的 公告正文 这一版的主线与目标 想知道「值不值得升」的

只看 Changelog 就够了:它是一行一条的白名单, speechnorm audio filter 这样一行行往下排, 想知道「我这版有没有某个东西」,比翻文档快得多。

至于「删了什么」,Changelog 里也写,但只写一行名字, 不告诉你替代品是什么——这一部分就得回头看 APIchanges。 命令行用户基本用不到这一层,遇到「这个参数忽然不认了」再去查也不迟。

六、动手 Demo:一次问出六个库版本

ffmpeg -version 会把这一串全打出来,但只打第一行是看不出结构的。 下面这段直接把每个库的大版本号单独拎出来。

import av

print("PyAV %s" % av.__version__)
for k in ("libavcodec", "libavformat", "libavfilter",
          "libavutil", "libswscale", "libswresample"):
    print("%-14s %s" % (k, ".".join(str(x) for x in av.library_versions[k])))

实跑输出:

--------------------------------------------------------------------
11.1.1 FFmpeg 5.0 的官网简介
--------------------------------------------------------------------

**① 一次问出三套版本号**

  看到的是      本机的值        它到底是什么
  ------------------------------------------------------------
  PyAV          18.1.0          Python 绑定自己的版本
  libavcodec    62.28.102       真正干编解码的库
  libavformat   62.12.102       管容器读写
  libavfilter   11.14.102       管滤镜
  libavutil     60.26.102       公共设施,时间基就在这儿
  libswscale    9.5.102         管像素格式转换

**这些数字里藏着好几套各算各的大版本:**
**`62` 是 libavcodec 的 ABI 大版本,`11` 是 libavfilter 的,`60` 又是 libavutil 的。**
**而「FFmpeg 5.0」这个发行版本号,在这些数字里一个都找不到。**

**这就是最容易混的一处:**
**「FFmpeg 5.0」是给整套源码打的标签,「62.28.102」是编译出来的某个库的编号。**
**两者之间只有一张对照表,没有算术关系。**
**想知道手上这套是哪个发行版,只能查表或者看 `ffmpeg -version` 第一行。**

**按 ABI 大版本对照,本机这一套(libavcodec 62)属于 FFmpeg 8.0 系列——**
**比本章要装的 5.0 高三个大版本。**
**这个「本机比书上新」的事实很重要:后面几节说的「5.0 上的命令」**
**在本机照样能跑,正好说明命令行这一层是稳定的。**

**② 5.0 到底改了什么**

  5.0 的变化                  影响谁
  ------------------------------------------------------
  编解码 API 统一成一套       写 C 的人,跟命令行无关
  旧解码 API 全部移除         还在用 2013 年接口的程序
  libavresample 整库删掉      自己调重采样的项目
  swscale 换成新 API          写 C 的人
  Vulkan 大改、加 libplacebo  想要 GPU 滤镜的人
  支持杜比视界                做 HDR 片源的人
  AAC 编码器默认参数调整      命令行用户唯一会碰到的

**这张表最该记住的是最后一行:前六项都跟命令行用户没关系。**
**5.0 是一次「拆地基」的大版本,拆的是库的接口,不是命令的写法。**
**所以书里 11.2~11.5 那四节「用 FFmpeg 5.0 实现 XX」,**
**命令跟前面几章一个字都不差——这不是作者偷懒,是本来就没变。**

**5.0 的发布日是 2022 年 1 月 17 日,代号 Lorentz;这次大版本一共删掉了**
**八十多个「废弃已久」的接口,是 FFmpeg 历史上动静最大的一次清理。**
**所以「5.0 变化很大」这句话是真的,但变化全在库那一侧。**

六行里最该记住的是前三行的大版本号:62、62、11。 它们跟「FFmpeg 5.0」这个数没有任何换算关系,只能查表。

顺带一句:PyAV 那行 18.1.0 是 Python 绑定自己的版本, 它跟 FFmpeg 的版本是两条独立的版本线,别拿它当 FFmpeg 版本用。

30 秒实验

  1. 把 libavcodec 换成 libavdevice:看它版本号跟 format 那个是否一致。
  2. 在同一台机器上装两个 ffmpeg:对比 ffmpeg -version 第一行与这里六行的对应关系。
  3. 去官网翻 5.0 的 Changelog:数一数新增的滤镜一共几行。

常见误区

  1. 把 PyAV 的版本当 FFmpeg 版本。两条版本线,互不对应。
  2. 以为 libavcodec 62 就是 FFmpeg 6.2。62 是 ABI 大版本,跟发行版号无关。
  3. 以为 5.0 改了命令写法。改的是库接口,命令行一个参数都没动。
自测三问(点开对答案) 1. FFmpeg 5.0 是哪天发布的,代号是什么? —— 2022 年 1 月 17 日,代号 Lorentz。 2. 「FFmpeg 5.0」和「libavcodec 62」是什么关系? —— 两个独立的编号体系,只能查表对照,没有算术关系。 3. 5.0 里命令行用户唯一会碰到的变化是什么? —— AAC 编码器的默认参数被调整过,不写 `-b:a` 时输出可能不一样。

相关笔记