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

530 个能解,占编解码器表的 95%,是编码器的 2.5 倍。 能解码不等于能播——播放器自带的解码器比这少得多。

📝 本节和前面几节的关系

3.11.5 讲能编的那 211 个,这一节讲能解的 530 个。 两个数一比,就能解释「ffplay 能放但浏览器放不了」这类问题。

一、95% 这个比例意味着什么

把总数拆开,能解的占了绝大多数:

能力 数量 占比


只能解 346 62% 能解也能编 184 33% 解码器合计 530 95% 编解码器总数 557 100%

解码器比编码器多 2.5 倍,原因很朴素: 世界上出现过的格式远多于「值得重新编码」的格式,能读就行,不必能写。

第一行 62% 是最值得注意的:这 346 个格式只能解、不能编。 它们的存在就是「历史包袱」这个词最具体的解释。

二、能解码不等于能播

这是本节最实用的一段,它解释了一大类「文件没坏但放不了」:

层次 谁来解 差异


ffmpeg 命令行 libavcodec 530 个全能用 系统播放器 自带解码器 通常几十个 浏览器 内置解码器 更少,只认主流几个

所以「ffplay 能放、浏览器放不了」不是文件坏了,是对方的解码器少。 解法不是修文件,是转成一个浏览器认识的编码(h264 加 aac)。

这条差异还有一个反向用法:选输出编码时以最弱的那个播放器为准。 要给浏览器看就一路 h264,别为了省点码率选个冷门编码。

三、硬解与软解在表里是两个条目

同一个格式,软件解和硬件解是两条独立的记录:

形态 例子 特点


软件解码 h264 CPU 算,什么机器都能跑 硬件解码 h264_qsv/h264_cuvid 要特定显卡,快但挑机器

本机这份是通用构建,硬件解码那几条不一定在——要 -decoders | grep qsv 查。 查不到不代表机器不支持硬解,可能只是这份二进制没编那一块。

这个「查不到有两种原因」的坑,在 3.11.4 的设备那一节也出现过一次。 凡是「清单里没有」的现象,都要先分清是「没编进去」还是「机器不支持」。

四、动手 Demo:530 个能解,2.5 倍于编码器

把方向再翻一次:只统计能解的,然后与能编的对比。 最后再看一个具体解码器的硬件加速配置数——这个数不为 0 说明它能交一部分活给显卡。

import av

both, donly = 0, 0
for n in av.codecs_available:
    try:
        r = av.codec.Codec(n, u"r")
    except Exception:
        continue
    if not r.is_decoder:
        continue
    try:
        w = av.codec.Codec(n, u"w")
    except Exception:
        donly += 1
        continue
    if w.is_encoder:
        both += 1
    else:
        donly += 1

print(u"能解合计   %d" % (both + donly))
print(u"其中只能解 %d" % donly)
print(u"两边都能   %d" % both)

c = av.codec.Codec(u"h264", u"r")
print(u"解码器     %s" % c.name)
print(u"硬件配置数 %d" % len(c.hardware_configs or []))

实跑输出:

--------------------------------------------------------------------
3.11.6 -decoders——530 个能解,占绝大多数
--------------------------------------------------------------------

**① 解码器占了编解码器表的 95%**

  能力             数量     占比
  ----------------------------------
  只能解           346      62%
  能解也能编       184      33%
  解码器合计       530      95%
  编解码器总数     557      100%

**解码器比编码器多 2.5 倍,原因很朴素:**
**世界上出现过的格式远多于「值得重新编码」的格式,能读就行,不必能写。**

**② 能解码不等于系统播放器能播**

  层次              谁来解         差异
  -------------------------------------------------------
  ffmpeg 命令行     libavcodec     530 个全能用
  系统播放器        自带解码器     通常几十个
  浏览器            内置解码器     更少,只认主流几个

**这解释了「ffplay 能放但浏览器放不了」这类问题:不是文件坏了,是解码器少。**
**解法不是修文件,是转成一个浏览器认识的编码(h264+aac)。**

**③ 硬件解码和软件解码,在表里是两个条目**

  形态         例子                     特点
  ----------------------------------------------------------------
  软件解码     h264                     CPU 算,什么机器都能跑
  硬件解码     h264_qsv/h264_cuvid     要特定显卡,快但挑机器

**本机这份是通用构建,硬件解码那几条不一定在——要 `-decoders | grep qsv` 查。**
**查不到不代表机器不支持硬解,可能只是这份二进制没编那一块。**

**④ 解码器也能查出细节**

  项                   值
  ------------------------------------------------------------------
  名字                 h264
  完整名               H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
  能解的像素格式数     0
  硬件加速配置数       5

**最后一行是个有用的信号:硬件加速配置数不为 0,说明这个解码器能交一部分活给显卡。**
**具体有哪几种、支持不支持,3.11.8 那一节会展开。**

「能解合计」这个数除以能编的那个数,就是本节标题里的倍数关系。 两个数都随构建变化,但「解远多于编」这个方向不会变。

最后一行是硬件加速的入口:配置数不为 0,说明这个解码器能交活给显卡。 具体有哪几种、哪几种在这台机器上可用,3.11.8 那一节展开讲。

h264 这个名字值得注意:它是内置解码器,与 libx264 不是一回事。 -c:v h264 走的是 FFmpeg 自研的那一套,-c:v libx264 走外挂库,两者参数集不同。

30 秒实验

  1. 数能解的:ffmpeg -decoders | wc -l,与 -encoders 对比倍数。
  2. 查硬解:ffmpeg -decoders | grep qsv,没有就说明这份构建没编硬件解码。
  3. 转成通用格式:ffmpeg -i 冷门.mp4 -c:v libx264 -c:a aac 出.mp4,给浏览器看。

常见误区

  1. 以为 ffplay 能放就等于别人也能放。解码器数量差着几百个,浏览器只认主流几个。
  2. 把 h264 和 libx264 当成同一个编码器。一个是内置解码器,一个是外挂编码库,参数不通用。
  3. 查不到 h264_qsv 就断定机器不支持硬解。可能只是这份构建没编那一块。
自测三问(点开对答案) 1. 为什么解码器数量远多于编码器? —— 因为历史上出现过的格式很多,能读就够了;值得重新编码的格式少得多。 2. ffplay 能放、浏览器放不了,怎么解释? —— 两者的解码器数量差很多:ffmpeg 有几百个,浏览器只内置主流几个,不是文件坏了。 3. `-decoders` 里查不到 `h264_qsv`,有哪两种可能? —— 一是这份构建没编硬件解码模块,二是机器确实没有对应的硬件;要分开排查。

相关笔记