一、音频延时全景图:Android音频通路概览、延时的定义与测量方法、常见场景的延时指标
各位同学,咱们今天聊一个老生常谈但又绕不开的话题——音频延时。说实话,我做了这么多年Android音频,最头疼的就是这个“延时”。你想想看,用户唱歌时听到自己的声音慢了半拍,或者视频通话里对方嘴巴动了半天声音才传过来,这种体验基本就是灾难。
所以第一节课,咱们先把全景图铺开。搞清楚音频在Android系统里到底是怎么跑的,延时从哪来,怎么量,以及不同场景下到底多少延时才算“及格”。
1.1 Android音频通路概览
先看一张我画的通路图。别被吓到,其实核心链路就那么几段。
从App调用AudioTrack.write()开始,数据经过Framework的AudioFlinger混音,再到HAL层,最后通过ALSA驱动送到扬声器。反过来录音路径也一样,只是方向相反。
每个环节都会引入延时。我见过不少开发者只盯着App层优化,结果发现底层Buffer一卡,前面全白费。嗯,这里要注意——延时是累加的,短板效应非常明显。
核心结论:Android音频通路从App到物理设备,至少经过4~6个缓冲区。每个缓冲区的大小直接决定了延时下限。
1.2 延时的定义与测量方法
什么叫音频延时?说白了就是从声音产生到被听到的时间差。但实际工程里,我们得区分几个概念:
- 端到端延时 (Round-trip latency):从麦克风采集到扬声器播放的总时间。VoIP、K歌最关心这个。
- 播放延时 (Output latency):从App写数据到扬声器出声的时间。
- 录音延时 (Input latency):从麦克风收音到App读到数据的时间。
怎么测?我分享两个我常用的土办法:
方法一:Loopback 硬件测量
用一根音频线把手机耳机孔的输出和输入短接。App播放一个脉冲信号,同时录音。然后看两个脉冲之间的时间差。这个方法最准,但需要硬件转接头。
// 伪代码示意
playPulse(); // 播放脉冲
startRecord();
while (recording) {
if (detectPulse(recordedData)) {
latency = currentTime - pulsePlayTime;
break;
}
}
方法二:软件时间戳法
Android 从 API 24 开始提供了 AudioTimestamp 接口。可以拿到硬件播放的位置和对应的时间戳。我个人习惯用这个做日常调试,不用额外硬件。
AudioTrack track = new AudioTrack(...);
AudioTimestamp ts = new AudioTimestamp();
// 获取硬件播放位置
track.getTimestamp(ts);
// ts.framePosition 是硬件已播放的帧数
// ts.nanoTime 是对应的系统时间
// 延时 = (App写入帧数 - 硬件播放帧数) / 采样率
小技巧:用 dumpsys media.audio_flinger 可以快速查看当前AudioFlinger的Buffer配置和延时估算值。我排查问题时经常先跑这条命令。
1.3 常见场景的延时指标
不同场景对延时的容忍度天差地别。咱们直接看表:
| 场景 | 可接受延时 | 优秀延时 | 关键瓶颈 |
|---|---|---|---|
| VoIP 通话 | < 150ms | < 50ms | 录音+网络+播放 |
| K歌 / 耳返 | < 30ms | < 10ms | 播放路径Buffer |
| 直播推流 | < 200ms | < 80ms | 编码+网络+播放 |
| 游戏音效 | < 50ms | < 20ms | 播放路径+混音 |
你看,K歌场景要求最苛刻——30ms以内。为什么?因为人耳对自声音的延时极其敏感。超过30ms,唱歌的人就会觉得“声音跟不上了”,俗称“延迟感”。
我曾经在一个K歌项目里踩过坑。当时用默认的AudioTrack配置,播放延时直接飙到80ms。用户反馈“唱歌像在跟读”。后来我把Buffer大小从默认的4帧改成了2帧,配合PERFORMANCE_MODE_LOW_LATENCY,才压到15ms左右。
避坑指南:千万不要在VoIP或K歌场景里用MODE_STREAM配合大Buffer。我曾经见过有人图省事直接设了256ms的Buffer,结果用户投诉“声音对不上嘴型”。记住:低延时场景必须用MODE_STATIC或极小的Stream Buffer。
再说直播。直播的延时容忍度其实比K歌高,因为用户通常不介意看到画面比声音晚一点点。但推流端(主播侧)的耳返延时必须低,否则主播自己唱不下去。所以直播场景里,本地耳返路径和推流路径要分开优化。
VoIP通话呢?150ms以内是行业标准。但如果你能做到50ms以下,用户体验会有质的飞跃。我记得有一次帮一个VoIP厂商优化,他们原本延时120ms,用户反馈“还行”。优化到40ms后,用户说“感觉像面对面说话”。
小结
这一章咱们把全景图铺开了。你知道了音频数据在Android系统里怎么流动,延时怎么定义和测量,以及不同场景下该追求什么指标。说白了,优化延时之前,先得知道你的目标是多少。
下一章我会深入讲AudioTrack和AudioRecord的低延时配置,包括Buffer大小怎么选、PerformanceMode怎么用、以及那些坑了我好几年的API细节。到时候咱们手把手调参数。
公众号:蓝海资料掘金营,微信deep3321