4. 音频流基础概念:音频编码原理(AAC, MP3)、采样率、声道数、音频比特率、音频重采样
音频处理,说白了就是跟「声音的数字化」打交道。很多做视频的同学容易忽略音频,觉得「不就是个声儿嘛」。但我在项目中踩过不少坑——视频画质调得再好,音频一卡顿、一爆音,用户直接关播放器。所以这一章,咱们把音频的底子打扎实。
4.1 声音是怎么变成数字的?
声音是连续的波。计算机没法存连续的东西,只能「采样」——每隔一小段时间记一个点。这个记点的频率,就是采样率。
我习惯把采样率理解成「拍照的帧率」。每秒拍 44100 张照片,就能还原出人耳能听到的所有频率。为什么是 44100?因为人耳上限约 20kHz,根据奈奎斯特定理,采样率得是最高频率的两倍以上。44100 就是这么来的。
| 采样率 | 常见用途 | 质量等级 |
|---|---|---|
| 8000 Hz | 电话语音 | 可听懂,但闷 |
| 16000 Hz | VoIP、语音识别 | 清晰语音 |
| 44100 Hz | CD 音质、MP3 | 高保真 |
| 48000 Hz | 电影、广播、FFmpeg 默认 | 专业级 |
| 96000 Hz | 高解析音频 | 发烧友级别 |
4.2 声道数:单声道、立体声、5.1
声道数就是「几个喇叭出声」。单声道一个通道,立体声左右两个,5.1 是六个(前左、前右、中置、后左、后右 + 低音炮)。
我在做直播项目时遇到过一个问题:推流端采集的是立体声,但观众端很多手机只有单声道喇叭。结果人声在左右声道来回飘,听着像「鬼畜」。后来我强制在服务端做了一次声道下混,把立体声合并成单声道,问题就解决了。
FFmpeg 里声道布局用 channel_layout 表示,常见的有:
mono— 单声道,1 通道stereo— 立体声,2 通道5.1— 六通道7.1— 八通道
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 | 发烧级,流媒体很少用 |
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 编码器,老牌但稳定
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% 还原原始波形。所以能不重采样就别重采样。
4.6 音频知识体系总览
下面这张图把音频基础概念串起来了。从模拟信号到数字信号,再到编码和输出,每一步都有对应的参数和工具。
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 里只做一次重采样,不要反复转。
嗯,音频基础就聊到这儿。这些概念看着简单,但实际项目中处处都是坑。把采样率、比特率、声道数这三个参数吃透,音频处理就稳了一半。