【问题标题】:How to use AudioTrack.getTimestamp() on Android to calculate latency?如何在 Android 上使用 AudioTrack.getTimestamp() 计算延迟?
【发布时间】:2018-03-30 20:31:38
【问题描述】:

我看到许多资源建议在现代 Android 版本上使用 AudioTrack.getTimestamp() 来计算音频/视频同步的音频延迟。

例如:

https://stackoverflow.com/a/37625791/332798

https://developer.amazon.com/docs/fire-tv/audio-video-synchronization.html#section1-1

https://groups.google.com/forum/#!topic/android-platform/PoHfyNK54ps

但是,这些都没有解释如何使用时间戳来计算延迟?我正在努力弄清楚如何处理时间戳的 framePosition/nanoTime 以得出延迟数字。

【问题讨论】:

    标签: android audio audiotrack


    【解决方案1】:

    因此,在此 API 之前,您将使用 AudioTrack.getPlaybackHeadPosition(),这只是一个近似值。因此,要考虑延迟,您必须使用以下两种隐藏方法之一的延迟值来抵消该值:AudioManager.getOutputLatency()AudioTrack.getLatency()

    使用新的AudioTrack.getTimestamp() API,您可以直接在输出端获取播放头位置在给定时间的快照。因此,它是完全准确的,并且已经考虑了设备延迟。因此,现在无需调用任何其他 API 来添加/删除延迟。

    需要注意的是,这个时间戳只是一个快照,文档建议你不要经常调用这个新方法。因此,获得“当前”位置的诀窍是使用您的最后一个快照并线性插值当前值应该是什么:

    playheadPos = timestamp.framePosition + 
                  (System.nanoTime() - timestamp.nanoTime) * samplerate / 1e9;
    

    然后可以将此位置与您写入AudioTrack 的帧数进行比较,方法是维护另一个计数器,每次AudioTrack.write() 完成时递增:

    int bytesWritten = track.write(...);
    writtenPos += bytesWritten / pcmFrameSize;
    

    如果您使用的是ENCODING_AC3,则AudioTrack 报告的播放头位置仍以样本为单位。您要么需要将其转换为字节,要么将您写入的字节数转换回样本。无论哪种方式,您都需要知道您的 AC3 流的比特率(即384000bps

    int bytesWritten = track.write(...);
    writtenPos += bytesWritten * samplerate / (bitrate / 8);
    

    【讨论】:

      猜你喜欢
      • 2013-12-15
      • 1970-01-01
      • 2013-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-26
      相关资源
      最近更新 更多