🎬 第三章 FFmpeg三大常用工具及应用选项详解
📄 一句话概括

-formats 打的是这份构建能读能写的容器格式清单,一共 414 个。 每个前面带字母标记:d 能读、e 能写、de 两样都行。

📝 本节和前面几节的关系

3.10 讲的是「怎么查」,从这一节开始逐个查那批清单。 六节各查一类:格式、封装、解封装、设备、编码器、解码器。

一、两列字母决定这个格式能干什么

清单里每行形如 DE mp4 MP4 (MPEG-4 Part 14),开头那两个字母是能力标记:

标记 含义 带这个标记的格式数


d demuxing,能读(解封装) 368 e muxing,能写(封装) 182 de 两样都能 136

第一二行加起来不等于 414,因为「读写都行」那 136 个在两个标记里各算了一次。 所以 -demuxers 的行数是 368、-muxers 是 182,交集就是那 136。

这个「交集被重复计数」的特点是理解三张表关系的关键: -formats 是全集,另外两张是它的两个方向上的切片。

二、按能力分成三类,看总数怎么凑出来

把 414 拆开,三类各占多少一目了然:

能力 格式数 标记 典型例子


只能读 232 d 各种老采集格式 只能写 46 e 输出专用的封装 读写都行 136 de mp4、mkv、flv、ts 合计 414 — 就是 -formats 的行数

「只能读」的那 232 个多是老格式:能解出来给人看,没人再往里写新内容。 「只能写」的 46 个多是输出专用:运行时才生成,不代表是一个磁盘上的文件。

这个分布和 3.11.3、3.11.5 那两节讲的「读多写少」是同一件事的两个侧面。 记住这条规律,以后见到「这个格式怎么不能输出」时就不会意外了。

三、这个数为什么会随构建变

-formats 打的是「编译进这份 libavformat 的东西」,不是「FFmpeg 理论上支持的」。 所以官方完整版、系统包管理器版、自己编的版本,三个数可以完全不同。

版本来源 格式数大概 差别在哪


官方完整构建 最多 外挂库都编进去了 发行版仓库版 中等 按许可证剔掉一部分 自己编的精简版 最少 只要用到的那些

这就解释了 1.1.2 那个现象:同一段命令在别人机器上能跑,在你这里报找不到格式。 不是命令错了,是你这份构建里没有那个组件。

所以「查清单」这件事要养成两个习惯:查自己机器上的,别信网上截图里的数字。 以及,拿到一份别人写的脚本时,先看它依赖的格式在不在。

四、动手 Demo:414 个格式,按读写能力分三类

沙箱里没有 ffmpeg.exe,-formats 打不出来。 但这张表的内容来自 libavformat 注册的组件清单,库这一层能遍历同一批组件。 这一段把「能读多少、能写多少、都能多少」三个数数出来。

import av

names = sorted(av.formats_available)
inn, out, both = [], [], []
for n in names:
    try:
        r = av.format.ContainerFormat(n)
    except Exception:
        continue
    if r.is_input and r.is_output:
        both.append(n)
    elif r.is_input:
        inn.append(n)
    else:
        out.append(n)

print(u"格式总数   %d" % len(names))
print(u"只能读     %d" % len(inn))
print(u"只能写     %d" % len(out))
print(u"读写都行   %d" % len(both))
print(u"d 标记合计 %d" % (len(inn) + len(both)))
print(u"e 标记合计 %d" % (len(out) + len(both)))

实跑输出:

--------------------------------------------------------------------
3.11.1 -formats——414 个格式,按读写能力分三类
--------------------------------------------------------------------

**① 两列字母 D 和 E,决定这个格式能干什么**

  标记     含义                         带这个标记的格式数
  ------------------------------------------------------------
  d        demuxing,能读(解封装)     368
  e        muxing,能写(封装)         182
  de       两样都能                     136

**注意第一二行加起来不等于 414:因为「读写都行」那 136 个在两个标记里都算了一次。**
**所以 `-demuxers` 的行数是 368,`-muxers` 是 182,两者的交集就是那 136 行。**
  能力         格式数     标记     典型例子
  ---------------------------------------------------------
  只能读       232        d        各种老采集格式
  只能写       46         e        输出专用的封装
  读写都行     136        de       mp4、mkv、flv、ts
  合计         414        —        就是 -formats 的行数

**只能读的多是老格式:能解出来但没人再往里写。**
**只能写的多是输出专用:运行时生成,不代表是一个「文件」。**

**② 这个数为什么会随构建变**

**`-formats` 打的是「编译进这份 libavformat 的东西」,不是「FFmpeg 理论上支持的」。**
**所以官方完整版、系统包管理器版、自己编的版本,三个数可以完全不同。**

**这也解释了 1.1.2 那个现象:同一段命令,在别人机器上能跑,在你这里报找不到格式。**
**不是命令错了,是你这份构建里没有那个组件。**

**③ 查一个具体格式在不在,别靠翻表**

  想确认               命令                            看什么
  ---------------------------------------------------------------------
  格式在不在           ffmpeg -formats | grep 名字     有没有那一行
  能不能写             同上,看 e 标记                 有没有 e
  某文件是什么格式     ffprobe -show_format            format_name

**第一行的 `grep` 是日常最高频的一条命令,比记格式名有用。**
**注意要 grep 小写——FFmpeg 的格式名区分大小写。**

最后两行就是 -demuxers 与 -muxers 的行数,而它们加起来比总数多出 136。 这个「多出来的部分」正是「读写都行」那一类被算了两遍, 所以三张表对不上不是数据错了,是统计口径不同。

第一行 414 和真 ffmpeg 上的数字不一定一样,这不是 bug。 沙箱里的这 414 是 PyAV 打包进来的那份 libavformat 的组件数, 换一份构建,三个数都会变——这正是本节第三段要讲的那件事。

「只能写」这一类最容易让人意外:居然有格式读不了自己写的文件。 它们多是 pipe:、fd:、md5 这类「目的地」而不是「文件格式」, 所以「读」这个概念对它本来就不成立。

30 秒实验

  1. 数列数:ffmpeg -formats | wc -l,和自己那份构建的 414 对比。
  2. 查一个格式:ffmpeg -formats | grep mp4,看它前面是 D、E 还是 DE。
  3. 只列能写的:ffmpeg -muxers,这个数就是 -formats 里带 e 的那些。

常见误区

  1. 把 -formats 的行数当成「能读的格式数」。里面有一半多是只能写的,得看字母标记。
  2. 以为三个数加起来该等于 414。d 与 e 两个口径都含「读写都行」,重复计数是正常的。
  3. 拿网上截图里的格式数当标准。这个数完全取决于编译时带了哪些库。
自测三问(点开对答案) 1. `-formats` 里 `DE` 这个标记说明什么? —— 既能解封装也能封装,也就是这个格式既能读也能写,比如 mp4、mkv。 2. `-demuxers` 368 行、`-muxers` 182 行,为什么加起来不是 414? —— 因为「读写都行」的 136 个在两个清单里都出现了一次,两边相加就多算了一遍。 3. 为什么同样一条命令在别人机器上能跑,在我这里报找不到格式? —— 因为格式是编译进二进制的,两份构建注册的组件不同,跟命令对错无关。

相关笔记