You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android中使用AudioTrack.getTimestamp()计算音频延迟?

我完全懂这种看了一堆资料却没拿到实操细节的困惑!之前做音视频同步的时候,我也对着AudioTrack.getTimestamp()卡了好久,现在把我摸透的实操逻辑分享给你:

用AudioTrack.getTimestamp()计算音频延迟&实现音视频同步

首先得先搞懂这个方法返回的AudioTimestamp对象里的两个核心字段——这是一切计算的基础:

  • framePosition:已经提交到音频硬件但还没播放的音频帧的起始位置(简单说就是“排队等着出声”的那批音频的开头帧号)
  • nanoTime:对应这个帧位置,硬件预计开始播放的系统纳秒时间(和System.nanoTime()用的是同一个时间基准,不受系统时钟调整影响)

1. 正确获取时间戳

建议在音频播放的周期性回调(比如AudioTrack.OnPlaybackPositionUpdateListener的onPeriodicNotification())里定期获取,或者在你需要做音视频同步的节点主动调用:

AudioTimestamp timestamp = new AudioTimestamp();
boolean isSupported = audioTrack.getTimestamp(timestamp);
if (!isSupported) {
    // 注意:部分旧设备/低版本Android不支持该方法,要准备降级方案(比如用getPlaybackHeadPosition()估算)
    return;
}

2. 计算当前音频播放延迟

延迟的核心计算逻辑很直接——因为nanoTime是硬件预计播放该帧的时间,用它减去当前的系统时间,就是这部分音频还要等多久才会被用户听到:

long currentSystemTime = System.nanoTime();
long playbackDelayNanos = timestamp.nanoTime - currentSystemTime;
  • 如果playbackDelayNanos是正数:说明这帧还要等这么久才会播放,数值就是当前的音频缓冲延迟
  • 如果是负数:说明这帧已经在播放中了(可能是调用时机的问题,取绝对值即可)

3. 关联音视频时间戳实现同步

要实现同步,你需要把音频的播放时间和视频的显示时间对齐:

  1. 先把音频的framePosition转换成时间戳(和视频用同一个时间基准,比如纳秒):
    long audioFrameTimeNanos = (timestamp.framePosition * 1_000_000_000L) / audioTrack.getSampleRate();
    
  2. 结合刚才算出的延迟,得到这个音频帧实际被用户听到的时间:
    long actualAudioPlayTimeNanos = audioFrameTimeNanos + playbackDelayNanos;
    
  3. 最后调整视频的显示时机:比如你的视频帧的显示时间戳是videoPtsNanos,如果videoPtsNanos比actualAudioPlayTimeNanos早,就暂停视频等音频追上;如果视频慢了,就丢帧让视频赶上来。

避坑提醒

  • 全程用System.nanoTime()作为时间基准,绝对不要用System.currentTimeMillis()——后者会受系统时间调整(比如手动改时间、NTP同步)影响,直接导致同步错乱
  • 不要太频繁调用getTimestamp(),比如每100ms调用一次就足够,太频繁会额外消耗性能
  • 一定要处理getTimestamp()返回false的情况,给旧设备留好降级方案

内容的提问来源于stack exchange,提问作者tmm1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:20:32