FFmpeg 不是「一个程序」,而是一组库加三个命令行工具。 库干活,工具只是壳。
前面六章全是协议,从这一章开始换视角:看现成的实现有哪些。 7.1.2 讲命令行怎么写,7.1.3 讲怎么用库。
一、库才是主体
实测这套环境里链着七个库: libavcodec、libavformat、libavfilter、libavdevice、 libavutil、libswresample、libswscale。 libavcodec 管编解码、libavformat 管封装与解封装、 libavfilter 管滤镜、libswscale 管像素格式、libswresample 管重采样。 libavutil 是地基——其它库都要用它,编不过它什么都干不了。
版本号能看出年代: libavcodec 已经是 62,libavutil 是 60。 这些主版本号加起来反映的是 API 的演进,跟「FFmpeg 版本号」不是一回事。
二、三个命令行工具
① ffmpeg:转码、转封装、切流、推流,一个工具全包。 ② ffprobe:只看不写——读流信息、读包信息。 ③ ffplay:一个极简播放器,主要用来验证「这条流能不能播」。
三个工具的代码量加起来不到这些库的一成。 它们做的事只有三件:解析命令行、按参数串起库调用、处理错误。 真正的工作量全在库里。
所以「会写 ffmpeg 命令行」离「会用 FFmpeg」还有一段距离。 命令行覆盖不到的场景(比如自定义滤镜链、逐帧控制)只能写代码。
三、为什么它是事实标准
① 格式覆盖最全:能想到的容器与编码基本都支持。 ② 命令行足够表达复杂流程:一条命令能串起解码、滤镜、编码、封装四步。 ③ 被大量项目内嵌:VLC、Chrome、各家媒体服务器都在用它。
第 ③ 条是它真正的护城河: 当所有流媒体软件都链着同一套库时, 「支持哪些格式」这个问题就变成了「FFmpeg 支不支持」。 于是大家更愿意直接用 FFmpeg,而不是自己写一套。
四、动手 Demo:FFmpeg 的模块——一组库,各管一摊
真读一遍这套环境里的库版本,再列清每个库的职责。 看清一件事:命令行工具只是这些库的壳。
import av
print("PyAV", av.__version__)
for k in sorted(av.library_versions):
print(" %-14s %d.%d.%d" % ((k,) + av.library_versions[k]))
print("共 %d 个库" % len(av.library_versions))
print()
duty = {
"libavformat": "封装与解封装",
"libavcodec": "编码与解码",
"libavfilter": "滤镜与缩放",
"libswscale": "像素格式转换",
"libswresample": "重采样",
"libavutil": "公共工具,其它库的地基",
}
for k, v in duty.items():
print(" %-14s %s" % (k, v))
实跑输出:
--------------------------------------------------------------------
FFmpeg 的模块——一组库,各管一摊
--------------------------------------------------------------------
**① 真读一遍这套环境里的库版本**
**PyAV 18.1.0,绑定的是 libav* 系列。**
库 版本
-------------------------------
libavcodec 62.28.102
libavdevice 62.3.102
libavfilter 11.14.102
libavformat 62.12.102
libavutil 60.26.102
libswresample 6.3.102
libswscale 9.5.102
**一共 7 个库,这就是「FFmpeg 其实是一组库」的直接证据。**
**② 各管一摊**
库 职责 少了它会怎样
---------------------------------------------------------
libavformat 封装与解封装 打不开文件
libavcodec 编码与解码 拿到帧也解不出
libavfilter 滤镜与缩放 只能原样进原样出
libswscale 像素格式转换 YUV 与 RGB 转不了
libswresample 重采样 采样率与声道改不了
libavutil 公共工具 其它库都编不过
**③ 命令行工具只是这些库的壳**
**ffmpeg 做转码、ffprobe 看信息、ffplay 播放。**
**三个工具加起来不到这些库的一成代码量——**
**真正的工作全在库里,工具只负责解析参数、串起调用。**
**所以「会写命令行」离「会用库」还有一段距离。**
七个库里 libavdevice 最容易忽略,它负责摄像头、屏幕这些采集设备。 libavcodec 是 62,而 libavutil 只有 60——主版本号各走各的,不代表强弱。 PyAV 只是把这些库包了一层 Python 接口,底层还是同一批 .dll。
30 秒实验
- 打印
av.library_versions的键,数一数有几个——七个,这就是「FFmpeg 是一组库」的直接证据。 - 加一行
av.open打开一个文件,看它报错提到哪个库——打不开文件是 libavformat 的错,解不出帧是 libavcodec 的错。 - 把
libswscale那一行去掉,想想会少什么能力——YUV 与 RGB 之间就转不了,截图功能会直接失效。
常见误区
- 「FFmpeg 就是一个命令行程序」——主体是七个库。
- 「ffmpeg 版本号就是库版本号」——两套编号,不能混。
- 「会写命令行就够了」——自定义滤镜、逐帧控制只能写代码。
自测三问(点开对答案)
1. FFmpeg 的主体是什么? —— **七个 libav* 库**;三个命令行工具只是它们的壳。 2. libavformat 与 libavcodec 各管什么? —— **封装解封装**与**编解码**,前者错在打不开,后者错在解不出。 3. 为什么它成了事实标准? —— **格式覆盖最全、命令行能表达复杂流程、被大量项目内嵌。**- ☐ (本节完,下一节 7.1.2 FFmpeg 命令行)