从零构建低延迟流媒体系统 - 第2节

数字音频基础:采样率、位深、声道

音频数字化,说白了就是把连续的声波变成一串离散的数字。我刚开始接触流媒体时,总觉得这步很简单——不就是把声音录下来吗?直到有一次做低延迟项目,回放出来的声音像机器人说话,我才意识到采样率和位深没选对,后果有多严重。

采样率:每秒“拍照”多少次

采样率决定了每秒从模拟信号中采集多少个样本点。单位是 Hz(赫兹)。

  • 8 kHz:电话语音质量,人声可懂但缺乏高频细节
  • 44.1 kHz:CD 音质,覆盖人耳 20 Hz ~ 20 kHz 的听觉范围
  • 48 kHz:影视行业标准,比 44.1 kHz 多留一点余量
  • 96 kHz / 192 kHz:高解析音频,常用于录音棚和高端监听
我的经验:低延迟直播场景,我一般用 48 kHz。44.1 kHz 虽然也能用,但很多音频设备原生就是 48 kHz 的时钟,省一次重采样就省几毫秒延迟。

位深:每个样本的“精度”

位深决定每个采样点用多少比特来表示。位深越大,动态范围越宽,信噪比越高。

位深 动态范围 典型场景
16-bit 96 dB CD、普通流媒体
24-bit 144 dB 录音棚、专业制作
32-bit float 理论无限 后期混音、科学计算
避坑:我曾经在嵌入式设备上用 32-bit float 做音频处理,结果 CPU 直接跑满。低延迟系统里,位深不是越大越好——16-bit 对大多数场景已经足够,24-bit 是安全选择,32-bit float 除非你有特殊需求,否则别碰。

声道:声音的空间感

声道数决定了声音的“维度”:

  • Mono(单声道):一路信号,适合语音、对讲
  • Stereo(立体声):左右两路,音乐、影视标配
  • 5.1 / 7.1:环绕声,家庭影院和游戏
  • Object-based(基于对象):Dolby Atmos 这类,每个声音独立定位

低延迟场景我建议优先用单声道或立体声。声道越多,编码和解码的计算量越大,延迟自然就上去了。


数字视频基础:分辨率、帧率、色彩空间

视频说白了就是快速播放一系列图片。但这里面有几个关键参数,直接影响画质和带宽。

分辨率:画面的“像素密度”

分辨率 = 宽度 × 高度(像素)。常见的有:

名称 分辨率 宽高比
480p 854 × 480 16:9
720p 1280 × 720 16:9
1080p 1920 × 1080 16:9
4K (UHD) 3840 × 2160 16:9
关键点:分辨率翻倍,像素数翻 4 倍。这意味着带宽和计算量也翻 4 倍。低延迟系统里,别盲目上 4K——1080p 在大多数场景下已经够用。

帧率:每秒多少张“照片”

帧率(fps)决定了运动的流畅度:

  • 24 fps:电影感,但快速运动时会有抖动
  • 30 fps:电视和网络视频标准
  • 60 fps:游戏、体育直播,非常流畅
  • 120 fps / 240 fps:慢动作拍摄或高端游戏

我个人习惯:低延迟直播用 30 fps 或 60 fps。30 fps 每帧有 33 ms 的处理时间,60 fps 只有 16.7 ms。帧率越高,编码压力越大,但用户感知的延迟也更低。

色彩空间:颜色的“坐标系”

色彩空间定义了如何用数字表示颜色。最常用的几个:

  • RGB:红绿蓝三原色,显示器原生格式
  • YUV:亮度(Y)+ 色度(U/V),视频压缩的基石
  • YCbCr:YUV 的数字版本,H.264/H.265 都用它

为什么视频不用 RGB?因为人眼对亮度变化比对颜色变化更敏感。YUV 可以把色度信息压缩到更低分辨率,比如 4:2:0 子采样——亮度全保留,色度只保留 1/4。这样带宽直接减半,画质损失几乎看不出来。

我的经验:做低延迟系统时,色彩空间转换是个容易被忽略的延迟点。尽量让采集端直接输出 YUV 4:2:0,避免在编码前做 RGB → YUV 的转换。我曾经在一个项目中因为采集卡只输出 RGB,硬生生多了 5 ms 的延迟。

视频编码原理:帧内预测、帧间预测、变换量化

视频编码的核心思想就一句话:去掉冗余。冗余分两种:空间冗余(同一帧内相邻像素相似)和时间冗余(相邻帧之间内容相似)。

帧内预测:去掉空间冗余

帧内预测(Intra Prediction)只使用当前帧内部的信息。编码器把图像分成一个个块(比如 16×16 或 4×4),然后用周围已经编码的像素来“猜”当前块的内容。

  • H.264:支持 9 种预测模式(方向)
  • H.265:支持 35 种预测模式
  • AV1:支持 56 种预测模式

模式越多,预测越准,但计算量也越大。低延迟场景下,我建议限制帧内预测的模式数量,别让编码器花太多时间在“最优模式选择”上。

帧间预测:去掉时间冗余

帧间预测(Inter Prediction)利用前后帧的相似性。编码器在当前帧中找一个块,然后在参考帧中搜索最匹配的块,只记录两者的位移(运动矢量)和残差。

这里有三种帧类型:

帧类型 描述 压缩率
I 帧 关键帧,独立编码,不依赖其他帧 最低
P 帧 前向预测,参考前面的 I 或 P 帧 中等
B 帧 双向预测,参考前后帧 最高
避坑:低延迟系统里,我建议禁用 B 帧。B 帧需要等待后面的帧编码完才能解码,会引入至少 1~2 帧的额外延迟。我曾经在一个实时通信项目里开了 B 帧,结果端到端延迟从 50 ms 飙到了 120 ms,排查了半天才发现是 B 帧搞的鬼。

变换量化:把残差“压缩”成系数

预测做完后,编码器得到的是残差(原始像素 − 预测像素)。残差通常很小,但直接存储仍然浪费空间。于是做变换(Transform)和量化(Quantization)。

  • DCT(离散余弦变换):把残差从空间域变换到频率域。低频系数集中在左上角,高频系数在右下角。
  • 量化:用量化矩阵除一遍,把小的系数变成 0。量化越狠,压缩率越高,但画质损失也越大。

量化参数(QP)是编码器最重要的控制旋钮之一。QP 越小,画质越好,码率越高;QP 越大,画质越差,码率越低。低延迟场景下,我一般用固定 QP 模式,而不是 VBR(可变码率),因为 VBR 的码率波动会导致网络拥塞和延迟抖动。


音频编码原理:感知编码、MDCT

音频编码和视频编码思路类似——去掉人耳听不到或听不敏感的部分。这就是感知编码(Perceptual Coding)的核心。

感知编码:只保留人耳能听到的

人耳有几个特性可以被利用:

  • 听觉阈值:人耳对不同频率的敏感度不同。2 kHz ~ 4 kHz 最敏感,低频和高频阈值高。
  • 掩蔽效应:一个强音会掩盖附近的弱音。比如一个 1 kHz 的大鼓声,会让旁边 950 Hz 的小提琴声听不见。
  • 时域掩蔽:强音前后几十毫秒内的弱音也会被掩盖。

编码器利用这些特性,把被掩盖的频率分量直接丢掉,只编码人耳能感知的部分。这就是为什么 MP3 和 AAC 能做到 10:1 的压缩比,听起来还“差不多”。

MDCT:音频编码的“心脏”

MDCT(改进型离散余弦变换)是现代音频编码的标准变换工具。它和视频里的 DCT 类似,但有几个关键区别:

  • 重叠处理:MDCT 对相邻帧有 50% 的重叠,避免块边界处的“块效应”
  • 时域混叠消除:编码时引入混叠,解码时通过 IMDCT 和重叠相加消除,保证完美重建
  • 窗函数:常用正弦窗或 Kaiser-Bessel 窗,控制频谱泄漏
关键点:MDCT 的帧大小直接影响延迟。AAC 默认 1024 个样本,在 48 kHz 下对应约 21 ms。低延迟场景可以用 512 或 256 样本的帧,但压缩效率会下降。我做过一个项目,为了把延迟压到 10 ms 以内,硬是把帧大小降到了 128 样本,配合 LD-AAC(低延迟 AAC)配置,效果还不错。

本章知识体系总览

下面这张图把本章的核心概念串起来了。你可以把它当作一张“地图”,后面每章都会在这张图上添加新的模块。

音视频基础原理知识体系 音视频基础原理知识体系 数字音频基础 采样率 位深 声道 数字视频基础 分辨率 帧率 色彩空间 视频编码原理 帧内预测 帧间预测 变换量化 音频编码原理 感知编码 MDCT 低延迟系统设计要点 • 音频:48 kHz / 16-bit / 单声道或立体声,MDCT 帧大小 256~512 样本 • 视频:1080p / 30~60 fps / YUV 4:2:0,禁用 B 帧,固定 QP 模式 • 编码器:限制帧内预测模式数量,优先用硬件编码器降低延迟

这张图把音频基础、视频基础、视频编码、音频编码四个模块的关系画清楚了。后面每一章都会围绕其中一个模块深入展开。你先把这张图记在脑子里,后面学起来会轻松很多。