4. 音频流基础概念:音频编码原理(AAC, MP3)、采样率、声道数、音频比特率、音频重采样

音频处理,说白了就是跟「声音的数字化」打交道。很多做视频的同学容易忽略音频,觉得「不就是个声儿嘛」。但我在项目中踩过不少坑——视频画质调得再好,音频一卡顿、一爆音,用户直接关播放器。所以这一章,咱们把音频的底子打扎实。

4.1 声音是怎么变成数字的?

声音是连续的波。计算机没法存连续的东西,只能「采样」——每隔一小段时间记一个点。这个记点的频率,就是采样率。

我习惯把采样率理解成「拍照的帧率」。每秒拍 44100 张照片,就能还原出人耳能听到的所有频率。为什么是 44100?因为人耳上限约 20kHz,根据奈奎斯特定理,采样率得是最高频率的两倍以上。44100 就是这么来的。

采样率 常见用途 质量等级
8000 Hz 电话语音 可听懂,但闷
16000 Hz VoIP、语音识别 清晰语音
44100 Hz CD 音质、MP3 高保真
48000 Hz 电影、广播、FFmpeg 默认 专业级
96000 Hz 高解析音频 发烧友级别
我的习惯:做流媒体时,统一用 48000 Hz。为什么?因为 FFmpeg 内部很多 filter 默认就是 48k,混流时少一次重采样,省 CPU。

4.2 声道数:单声道、立体声、5.1

声道数就是「几个喇叭出声」。单声道一个通道,立体声左右两个,5.1 是六个(前左、前右、中置、后左、后右 + 低音炮)。

我在做直播项目时遇到过一个问题:推流端采集的是立体声,但观众端很多手机只有单声道喇叭。结果人声在左右声道来回飘,听着像「鬼畜」。后来我强制在服务端做了一次声道下混,把立体声合并成单声道,问题就解决了。

FFmpeg 里声道布局用 channel_layout 表示,常见的有:

  • mono — 单声道,1 通道
  • stereo — 立体声,2 通道
  • 5.1 — 六通道
  • 7.1 — 八通道
注意:声道数越多,数据量越大。一个 5.1 的音频流,比特率是立体声的 3 倍左右。做流控时,别光盯着视频码率,音频也可能吃掉不少带宽。

4.3 音频比特率:码率与质量的平衡

比特率就是每秒用多少 bit 来存音频。它直接决定了文件大小和音质。

我见过不少新手直接给音频设 320kbps,觉得「越高越好」。其实没必要。对于 AAC 编码,128kbps 立体声已经接近透明音质了,再往上提升很小,但文件体积涨得很快。

编码 比特率 音质评价
MP3 128 kbps 可接受,有压缩感
MP3 192 kbps 不错,多数人听不出区别
MP3 320 kbps 接近 CD,但文件大
AAC 96 kbps 相当于 MP3 128k
AAC 128 kbps 透明音质,推荐
AAC 256 kbps 发烧级,流媒体很少用
实战建议:做直播时,音频用 AAC 128kbps 立体声,或者 96kbps 单声道。既保证音质,又不占太多带宽。我曾经把音频从 192k 降到 96k,观众完全没察觉,但整体码率降了 10%。

4.4 音频编码原理:AAC vs MP3

编码器的作用,就是把 PCM 裸数据压缩成更小的格式。PCM 是啥?就是采样后的原始数据,没压缩过。一个 CD 音质的 PCM 流,每秒要 1.4Mbps 左右,不压缩根本没法传。

MP3 是上世纪 90 年代的产物。它利用心理声学模型,把人耳不敏感的频率信息丢掉。说白了就是「听不见的就不存」。MP3 在低比特率下(128k 以下)表现还行,但到了 2024 年,技术上已经落后了。

AAC 是 MP3 的接班人。它用了更先进的滤波器组和编码算法,同样比特率下音质比 MP3 好一截。我个人的经验是:AAC 96kbps 约等于 MP3 128kbps。所以现在流媒体几乎清一色用 AAC。

FFmpeg 里常用的 AAC 编码器有:

  • aac — FFmpeg 内置的 AAC 编码器,质量不错
  • libfdk_aac — Fraunhofer 的 AAC 编码器,质量最好,但需要编译时开启
  • libmp3lame — MP3 编码器,老牌但稳定
我的选择:能用 libfdk_aac 就用它,质量确实好。如果编译环境不支持,FFmpeg 内置的 aac 编码器也够用。MP3 我只在兼容老旧设备时才会用。

4.5 音频重采样:为什么需要它?

重采样就是把音频从一个采样率转成另一个。比如你的源文件是 44100 Hz,但输出需要 48000 Hz,就得重采样。

为什么会需要?因为不同设备、不同标准用的采样率不一样。电影是 48k,CD 是 44.1k,语音采集可能是 16k。混流时如果不统一,FFmpeg 会报错或者输出奇怪的音频。

FFmpeg 里用 aresample filter 做重采样:

ffmpeg -i input.mp3 -af "aresample=48000" output.wav

这个命令把输入音频重采样到 48000 Hz。注意,重采样是有损的——算法会做插值,不可能 100% 还原原始波形。所以能不重采样就别重采样。

我曾经踩过的坑:有一次做多路混流,一路是 44.1k,一路是 48k。我没做重采样直接拼接,结果输出音频里出现了「啵啵」的爆音。后来排查了半天才发现是采样率不一致导致的。从那以后,我所有项目都统一用 48k,省心。

4.6 音频知识体系总览

下面这张图把音频基础概念串起来了。从模拟信号到数字信号,再到编码和输出,每一步都有对应的参数和工具。

音频处理核心流程 模拟信号 采样 采样率 (Hz) 量化 位深度 (bit) PCM 编码 (AAC / MP3) 比特率 (kbps) 输出流 声道数 / 布局 重采样 (aresample) 改变采样率 / 声道 关键参数总结: • 采样率:决定频率范围,流媒体推荐 48000 Hz • 比特率:决定压缩程度,AAC 128k 是甜点值 • 声道数:单声道省带宽,立体声体验好,按场景选

4.7 实战:用 FFmpeg 查看音频信息

说了这么多理论,咱们来点实际的。用 FFmpeg 查看一个音频文件的详细信息:

ffmpeg -i input.mp3

输出里你会看到类似这样的内容:

Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p, 192 kb/s

这行信息包含了:编码格式(mp3)、采样率(44100 Hz)、声道数(stereo)、采样格式(s16p,即 16 位有符号整型)、比特率(192 kb/s)。

如果你想看更详细的声道布局信息,可以加 -f lavfi 参数,或者用 ffprobe:

ffprobe -v error -show_entries stream=channel_layout input.mp3
小技巧:调试音频问题时,我习惯先用 ffprobe 把音频流的参数全部 dump 出来,确认采样率、声道数、比特率是否一致。很多音画不同步的问题,根源就是音频参数不统一。

4.8 避坑指南

  • 采样率不匹配:混流前一定要统一采样率,否则会出现爆音或音画不同步。
  • 比特率设太高:对于流媒体,AAC 128k 已经足够。设到 320k 只会浪费带宽,人耳听不出区别。
  • 声道数乱用:如果输出设备只有单声道,立体声信号会被下混,可能损失人声清晰度。提前做声道规划很重要。
  • 重采样次数过多:每次重采样都会引入失真。尽量在 pipeline 里只做一次重采样,不要反复转。

嗯,音频基础就聊到这儿。这些概念看着简单,但实际项目中处处都是坑。把采样率、比特率、声道数这三个参数吃透,音频处理就稳了一半。