🎬 第一章 音视频及流媒体播放原理
📄 一句话概括

声音是连续的气压变化,数字化就是「每隔一会儿量一次、每次量个整数」。 码率 = 采样率 × 位深 × 声道数,三个乘数各管一件事,互不替代。

📝 本节和前面几节的关系

上一节算清了画面的数据量,这一节算声音的。 两者放一起才好理解「为什么视频里音频只占几个百分点」:1080p30 未压缩是 746 Mbps, CD 音质只有 1.4 Mbps,差五百多倍。 但声音不能省——画面糊了还能忍,声音断了立刻出戏。 这也是为什么弱网下播放器常先降画质、很少降音质。

一、采样:把连续的波切成点

麦克风把气压变化变成电压,电压是一条连续曲线。 计算机存不了连续曲线,只能每隔一小段时间取一个值——这就是采样。

采样率就是「每秒取多少个点」。 采得越密,能表示的高频越高:采样率 8 kHz 只够电话语音,44.1 kHz 够音乐, 48 kHz 是视频行业的标准。

这里有一条硬约束,叫采样定理: 采样率必须大于信号最高频率的两倍,否则高频会「折」成低频,变成假声。 人耳上限约 20 kHz,两倍就是 40 kHz,所以 44.1 kHz 够用。 如果只采 8 kHz,那么 4 kHz 以上的声音都会被折回来变成刺耳的杂音。

这个「折叠」不是软件 bug,是数学必然: 采样之后你根本无法区分「4 kHz 的真信号」和「5 kHz 折回来的假信号」。 所以采样率一旦定死,能还原的带宽就定死了。

二、44.1 kHz 这个奇怪数字的来历

为什么不取整成 44 或 48,偏要 44.1? 因为它要跟当年的磁带录像机对齐:PAL 制式的行频是 15625 Hz,一行正好塞三个采样, 15625 × 3 = 46875,再乘个系数就落到了 44100。

这是典型的「工程妥协留下历史包袱」:今天没人再用磁带存音频,但 CD 定了 44.1, 几十年就改不动了。

而视频行业走另一条线,定了 48 kHz:因为早期数字录像设备(DAT)用它,后来电影、电视、 直播全跟着用。 所以一个播放器必须能重采样——素材是 44.1 kHz,声卡按 48 kHz 出,中间那一步就是 swr_convert。

三、位深:每次量多细

采样解决了「多久量一次」,位深解决「量得多细」。 16 位就是每个采样点用 65536 个刻度去量。

位深直接决定动态范围,公式是「位数 × 6.02 分贝」:

位深 刻度数 理论动态范围 典型用途
8 位 256 约 48 dB 老游戏、电话
16 位 65536 约 96 dB CD、绝大多数素材
24 位 16777216 约 144 dB 录音棚、影视后期

「96 分贝」听着抽象,换成日常场景:它大致是「最轻的呼吸声」到「最响的交响乐」的跨度。 所以 16 位对回放够用,24 位是给后期留余量用的——多出来的位不是让人听见更细, 是让录音师有空间调。

位深不足的表现不是「变糊」,是「底噪」:安静段落会听到沙沙声,那是量化误差被放大的结果。

四、声道:一次存几路

单声道是一路,立体声是左右两路,5.1 是六路(前左、前右、中置、低音、后左、后右)。

声道数直接乘进码率,所以是最贵的一项:48 kHz 16 位,立体声是 1536 kbps, 5.1 就是 4608 kbps——三倍。

但声道不是越多越好:手机上两个喇叭离得比耳朵还近,5.1 的信息量根本放不出来; 耳机倒是能靠 HRTF 做出环绕感,那是另一套算法(双耳渲染),不是「多存几路」就能解决的。

播放器这边要处理的是「布局不匹配」:素材是 5.1,输出是立体声, 就要下混(downmix)——把后环绕按比例并进左右,同时保证人声不飘。这一步也归 swr_convert 管。

五、压缩:AAC 在做减法

PCM 是把每个采样点原样存下来,一个字节都不省。 AAC 则在两个地方做减法: 一是心理声学——被强音盖住的弱音,人耳听不见,干脆不存。 二是冗余——波形里有大量可预测的部分,只存「与预测的差」。

所以 AAC 的码率是「预算」,不是「结果」:128 kbps 是硬指标,复杂的交响乐会被摊薄, 安静的独白也照花这么多。这一点跟视频的 CBR 是一样的脾气。

这也是为什么 AAC 在不同素材上表现差很多:人声谈话 64 kbps 就很干净, 金属摇滚 256 kbps 还嫌不够。心理声学模型假设「掩蔽效应」,而密集的宽带噪声几乎不产生掩蔽。

六、动手 Demo:声音比画面小得多,但也不是白给的

这段先把四种常见规格的 PCM 码率算出来,再真编一段 AAC 看压缩比。 注意最后一行 5.1——声道数一多,码率立刻翻三倍。

for name, sr, bits, ch in cases:
    b = sr * bits // 8 * ch        # 每秒字节数
    T([name, u"%d" % b,
       u"%.0f kbps" % (b * 8 / 1000.0),
       u"%.2f GB" % (b * 3600 / (1024.0 ** 3))], [0, 0, 0, 0])

# 真跑:2 秒 48 kHz 立体声,编码 AAC 128 kbps
pcm = 48000 * 2 * 2 * 2
n = _make_audio(path, 2.0, 48000)

实跑输出:

--------------------------------------------------------------------
声音比画面小得多,但也不是白给的
--------------------------------------------------------------------
**PCM 的码率是三样相乘:采样率 × 位深 × 声道数。**

  规格                        每秒字节     码率          一小时
  ------------------------------------------------------------------
  44.1 kHz/16 位/立体声     176400       1411 kbps     0.59 GB
  48 kHz/16 位/立体声       192000       1536 kbps     0.64 GB
  48 kHz/24 位/立体声       288000       2304 kbps     0.97 GB
  48 kHz/16 位/5.1          576000       4608 kbps     1.93 GB

**CD 音质是 1411 kbps,比 1080p 视频的 746 Mbps 小 529 倍。**
**这就是为什么早期网络视频总先砍画面、不砍声音。**

**真跑 2 秒 48 kHz 立体声**:
  PCM 的账是 384000 字节(192000 字节每秒 × 2 秒)。
  AAC 128 kbps 压完,文件实际 33616 字节。
  **压缩比 11.4 比 1,误差来自 ADTS 头与编码器填充。**

**注意 AAC 是按「码率」而不是按「质量」配的**:128 kbps 是个硬预算,复杂的音乐会被摊薄,
安静的段落也照花这么多。

压缩比十一倍多一点,误差来自 ADTS 头——AAC 裸流每帧前面有几个字节的头,两秒几十帧, 加起来几百字节。

这段测试音是 440 Hz 纯正弦,比真实音乐好压得多,所以这个压缩比偏乐观。 真实音乐在 128 kbps 下的压缩比也是十几倍,但主观听感差得多——因为纯音的掩蔽效应简单, 音乐的复杂得多。

最后记住一条实用的:音频码率低到 64 kbps 以下,人声还能忍、音乐就明显发闷; 视频会议把音频从 32 提到 64 kbps,体验提升比把画面从 720p 提到 1080p 大。因为人对声音的劣化比对画面敏感。

30 秒实验

  1. 查一下你常用会议软件的音频设置,看它给的采样率与码率是多少。
  2. 用「采样率 × 位深 × 声道 ÷ 8」算出它的 PCM 码率,再和实际码率比。
  3. 想一想:为什么手机录音常给 48 kHz 而不是 44.1 kHz?

常见误区

  1. 以为采样率越高声音越好。 超过两倍最高频率之后,再高的采样率对可听频段没有帮助, 只是让文件变大。
  2. 把位深当成「精度」而不是「动态范围」。 位深不足的表现是底噪,不是模糊;安静段落最先出问题。
  3. 以为立体声就是「两倍的数据、两倍的好听」。 它给的是空间定位,在单喇叭设备上要下混, 处理不好人声会变薄。
自测三问(点开对答案) 1. 为什么 CD 选 44.1 kHz 而不是 40 kHz? —— 40 kHz 只是「刚好两倍人耳上限」,没有余量; 44.1 kHz 留了抗混叠滤波器的过渡带,而且它的数字来自当年录像机的行频。 2. 16 位为什么是 96 分贝? —— 每个比特约 6.02 分贝,16 × 6.02 ≈ 96。这条公式对任何位深都成立。 3. 素材是 44.1 kHz、声卡按 48 kHz 出,中间发生什么? —— 重采样:按比例插值出新的采样点。 这一步在 FFmpeg 里是 `swr_convert`,它同时能处理声道布局转换。

画面和声音的账都算清了,下一个问题是「怎么把它们送到对面」——这就分出了下载、单播、 组播几条完全不同的路。

相关笔记