🎬 第十章 AAC编解码基础
📄 一句话概括

AAC 是编码,装成文件还有两种组织方式:ADIF 一个头管全文、ADTS 每帧带同步头——正是【存储】与【传输】两种需求的产物。

📝 本节和前面几节的关系

10.1 讲了 AAC 的编码,这一节讲这些编码结果怎么组织成一个文件或一段流。

一、为什么会有两种

同一个编码格式,为什么需要两种文件组织方式?因为使用场景不同: 存储场景——文件完整、可以随机访问,头的开销越小越好,放一份就够; 传输场景——数据是边来边放的,可能从中间开始、也可能丢一段,每一帧都必须能自己说明自己; 于是有了 ADIF 与 ADTS 两个名字。 这不是历史包袱,是两个需求的自然结果。

二、ADIF:一个头管全文

ADIF(Audio Data Interchange Format)的思路是【集中】: 整个文件只有一个头,放在最前面,写着采样率、声道、编码规格; 后面是连续的原始帧,帧与帧之间没有额外分隔; 优点是开销最小——头只写一次; 缺点也很明显:一旦丢了头,后面的数据没法解释,而且难以从中间开始解码。 所以 ADIF 主要出现在本地存储的裸音频文件里。

三、ADTS:每帧都带同步头

ADTS(Audio Data Transport Stream)的思路是【分散】: 每一帧前面都有一段头(7 或 9 字节); 头里有一个 12 位的同步字 0xFFF——解码器靠它在码流里重新找到帧边界; 头里还写着采样率索引、声道配置、编码档次、本帧长度; 所以任何位置拿到一段 ADTS 数据,只要能对上同步字,就能开始解码。 流媒体一律用 ADTS,正是因为这个【随到随解】的性质。

四、ADTS 帧头里有什么

那几个字节里装的信息,每一项都对应一个实际需求: 同步字 0xFFF——找回帧边界; 档次字段——告诉解码器这是 LC 还是其他档; 采样率索引——4 位,指向一张标准采样率表; 声道配置——单声道、立体声、5.1 等; 帧长度——本帧有多少字节,便于整帧取出; 还有一个 protection_absent 标志,决定后面有没有 CRC 校验。 每一项都是为了让【拿到一帧就能独立地解这一帧】。

五、后缀与封装的关系

最后把后缀、编码与封装三者的关系理一遍: .aac——绝大多数是 ADTS 格式的裸音频流; .m4a/.mp4——里面是 AAC,但外面套的是 MP4 封装(第 5.2.3 节); .ts——广播传输流里,AAC 通常也是 ADTS 形式; 所以同样是 AAC,可能装在三种完全不同的外壳里; 判断方式不变:用 MediaInfo 看容器与编码两栏(第 3.2.1 节)。

六、动手 Demo:AAC 的两种文件组织方式

AAC 是编码,装成文件还有两种组织方式。

rows = [("ADIF", "整个文件只有一个头,在开头", "本地文件存储", ".aac"),
        ("ADTS", "每一帧都带同步头", "流式传输、边收边放", ".aac")]
for a, b, c, d in rows:
    print("%-5s %-22s %-16s %s" % (a, b, c, d))

实跑输出:

--------------------------------------------------------------------
AAC 的两种文件组织方式
--------------------------------------------------------------------

AAC 是编码,装成文件还有两种组织方式。

  格式     头的位置                       用途                   典型后缀
  ------------------------------------------------------------------------
  ADIF     整个文件只有一个头,在开头     本地文件存储           .aac
  ADTS     每一帧都带同步头               流式传输、边收边放     .aac

  一句话区分这两个名字:
  **ADIF 是【一本书加一个目录】,ADTS 是【每页都写页码】。**
  所以流媒体一定用 **ADTS**——丢了一段也能靠同步字重新对上;
  **`.aac` 文件大多数是 ADTS**;而 `.m4a`/`.mp4` 里装的是 AAC,
  但用的是 MP4 的封装(第 5.2.3 节)。

一句话区分:ADIF 是【一本书加一个目录】,ADTS 是【每页都写页码】。 所以流媒体一定用 ADTS——丢了一段也能靠同步字重新对上。 .aac 文件大多数是 ADTS;.m4a/.mp4 里装的是 AAC,但用 MP4 封装。

30 秒实验

  1. 用 FFmpeg 从一段音乐提取音频:ffmpeg -i in.mp3 -c:a copy -f adts out.aac。
  2. 用十六进制工具看每帧开头的 0xFFF——那就是同步字。

常见误区

  1. 以为 .aac 与 .m4a 是同一种东西。里面的编码可能都是 AAC,外壳完全不同。
  2. 以为 ADIF 已经没用了。本地存储的裸流仍常见,只是流媒体不用它。
  3. 以为同步字只是个标记。它是【随到随解】能力的全部基础。
自测三问(点开对答案) 1. ADIF 与 ADTS 的核心区别是什么? —— ADIF 只有一个文件头,ADTS 每帧都带同步头。 2. 流媒体为什么用 ADTS? —— 每帧自带头与同步字,可从任意位置开始解码,丢包影响局部。 3. `.m4a` 里的 AAC 用的什么封装? —— MP4 封装,不是 ADTS。

相关笔记