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

声道模式就是「一个名字加一组声道位置约定」。 5.1 是 6 个声道不是 5 个——那个 .1 指的是低音声道。

📝 本节和前面几节的关系

3.11.8 讲视频侧的硬件,这一节转到音频侧的声道。 多声道素材出问题,十有八九是布局名字或者声道顺序弄错了。

一、九个常见布局,名字与声道数

名字拼对了才构造得出来,拼错直接抛异常:

名字 声道数 典型用途


mono 1 单声道,语音最省 stereo 2 立体声,最通用 2.1 3 左右加低音 3.0 3 左中右 quad 4 四声道环绕 5.0 5 环绕无低音 5.1 6 影院标配 6.1 7 多一个后中 7.1 8 蓝光标配

这九个在本机全部可用,名字全部拼对了才构造得出来。 拼错的表现是直接抛异常——这比「静默降级成单声道」好得多。

二、名字里的数字不能靠猜

5.1 是 6 个声道,不是 5 个,这一条最容易记错:

名字 以为几个 实际几个


5.1 5 6 6.1 6 7 7.1 8 8

规律是「小数点前的数加 1」:那个 .1 是一个额外的低音声道,不算在整数里。 7.1 那一行看着对上了,是因为它本来就写了 8——但这个巧合容易让人记错规律。

写脚本时更稳的办法是拿到布局对象读 nb_channels,别自己算。 算错一次就是整条音轨的声道被错位映射,比报错难查得多。

三、降混是自动的,结果不保证好听

声道数变少时系统会自动混,但混法是为「不削波」优化的:

转换 系统怎么处理 注意


5.1 → stereo 按权重混到两个声道 环绕感没了 stereo → mono 两路相加再衰减 可能相位抵消 mono → stereo 两路复制一份 没有真正的立体感

第一行的权重是 libswresample 内置的,可以用 -af pan 自己指定。 默认那套权重不一定是为「好听」优化的,专业场合要自己调。

第二行那个「相位抵消」是个具体现象:两路内容相近但反相时,相加会变小声。 表现是「转成单声道后人声突然变闷」——这不是文件坏了。

四、名字的隐藏用途:查声道顺序

布局名字背后是一张固定的声道顺序表,动多声道素材时必须按它来:

布局 声道顺序


stereo 前左、前右 5.1 前左、前右、中、低音、后左、后右 7.1 前左、前右、中、低音、后左、后右、侧左、侧右

写 -af channelmap 时必须按这个顺序填,填错就是把对白送到低音炮里。 这种错误听起来很荒谬,但它确实是最常见的一类多声道事故。

所以动多声道素材之前,先确认布局名,再确认顺序,两步都不能省。 只确认名字不够——5.1 和 5.1(side) 的声道定义就不一样。

五、动手 Demo:九个布局,逐个读出真实声道数

不靠记忆,直接把每个布局名字构造一遍,读它自己报的声道数。 这样「5.1 到底是几个声道」这种问题就有确定答案了。

import av

LAY = [(u"mono", u"语音"), (u"stereo", u"通用"), (u"2.1", u"加低音"),
       (u"3.0", u"左中右"), (u"quad", u"四声道"), (u"5.0", u"环绕"),
       (u"5.1", u"影院"), (u"6.1", u"后中"), (u"7.1", u"蓝光")]

for name, use in LAY:
    try:
        l = av.AudioLayout(name)
        print(u"%-8s %d 声道  %s" % (name, l.nb_channels, use))
    except Exception as e:
        print(u"%-8s 不支持  %s" % (name, use))

# 名字拼错会怎样
try:
    av.AudioLayout(u"5.2")
    print(u"5.2 竟然也构造出来了")
except Exception:
    print(u"5.2 构造失败,说明布局名是白名单")

实跑输出:

--------------------------------------------------------------------
3.11.9 -layouts——声道模式的名字与含义
--------------------------------------------------------------------

**① 声道模式就是一个名字加一组「哪个声道在哪」的约定**

  名字       声道数     典型用途
  ------------------------------------------
  mono       1          单声道,语音最省
  stereo     2          立体声,最通用
  2.1        3          左右+低音
  3.0        3          左右中
  quad       4          四声道环绕
  5.0        5          环绕无低音
  5.1        6          影院标配
  6.1        7          多一个后中
  7.1        8          蓝光标配

**本机这 9 种全部可用,名字全部拼对了才构造得出来。**
**拼错的表现是直接抛异常——这比「静默降级成单声道」好得多。**

**② 数字不能靠猜**

**`5.1` 是 6 个声道,不是 5 个——那个 `.1` 指的是低音声道。**
**`6.1` 是 7 个,`7.1` 是 8 个,规律一样。**

**所以「5.1 转 2.0」这种说法里的数字,跟声道数不是一回事,要查表。**
**写脚本时更稳的办法是:拿到布局对象读 `nb_channels`,别自己算。**

**③ 降混是自动的,但结果不保证好听**

  转换              系统怎么处理           注意
  -------------------------------------------------------------
  5.1 → stereo      按权重混到两个声道     环绕感没了
  stereo → mono     两路相加再衰减         可能相位抵消
  mono → stereo     两路复制一份           没有真正的立体感

**第一行的权重是 libswresample 内置的,可以用 `-af pan` 自己指定。**
**默认那套权重是为「不削波」优化的,不一定是为「好听」优化的。**

**④ 名字还有一个隐藏用途:查它的声道顺序**

**`5.1` 的六个声道顺序是固定的(前左、前右、中、低音、后左、后右),**
**写 `-af channelmap` 时必须按这个顺序填,填错就是把对白送到低音炮里。**
**所以动多声道素材之前,先确认布局名,再确认顺序,两步都不能省。**

打出来的声道数会逐行验证那条「小数点前加 1」的规律。 这是最省事的记法:不用背表,读一次就记住了。

最后那两行是「拼错会怎样」的对照实验:布局名是白名单,不在名单里直接失败。 这个行为比「猜一个最接近的」安全得多——错了立刻知道,不会静默降级。

注意 quad、mono 这些名字不带数字,所以规律只适用于带点号的那几个。 混着记的时候,还是以读出来的 nb_channels 为准。

30 秒实验

  1. 列布局:ffmpeg -layouts,注意它把音频布局和像素格式分两段打在一起。
  2. 降混:ffmpeg -i 5.1.wav -ac 2 出.wav,听环绕感丢了多少。
  3. 指定布局:ffmpeg -i 片子.mp4 -af aformat=channel_layouts=stereo 出.mp4,强制输出布局。

常见误区

  1. 以为 5.1 是 5 个声道。它是 6 个,那个 .1 是额外的低音声道。
  2. 以为降混是免费的。5.1 转 stereo 会按固定权重混,环绕感直接消失。
  3. 不确认声道顺序就写 channelmap。填错顺序就是把对白送进低音炮。
自测三问(点开对答案) 1. `5.1` 布局是几个声道?为什么? —— 6 个。小数点前是 5 个主声道,那个 `.1` 是一个独立的低音声道。 2. mono 转 stereo 之后听起来有立体感吗? —— 没有。它只是把同一路复制成两份,两个声道内容完全相同。 3. 布局名字拼错了会怎样? —— 直接抛异常。布局名是白名单,不会猜一个最接近的,所以错了立刻能发现。

相关笔记