我有一个将数据包排队到AudioQueue的应用程序,它运行良好。问题是当我在网络中出现延迟时,我无法及时向 AudioQueue 提供数据包。
所有应用程序都运行良好,enqueueBuffer 没有返回任何错误,但 AudioQueue 正在丢弃数据包(所以我没有声音),因为它们太旧了。
我是否可以强制 AudioQueue 播放这些音频数据包?或者至少知道数据包正在被丢弃?。因为如果我知道,我可以暂停播放以重新启动队列......(不是很好的解决方案,但我没有更好的解决方案)
因为延迟可能非常大,所以我不能使用大的缓冲区,因为这会最大限度地减少错误,但不能解决它
谢谢
你走在正确的轨道上。您可以通过在回调过程中检测何时到达网络缓冲区的末尾,然后暂停 AudioQueue 来处理网络延迟。稍后,一旦缓冲了足够的数据包,就会重新启动队列。您的代码将如下所示
if playerState.packetsRead == playerState.packetsWritten {
playerState.isPlaying = false
AudioQueuePause(aq)
}
在您的网络代码中
if (playerState.packetsWritten >= playerState.packetsRead + kNumPacketsToBuffer) {
if !playerState.isPlaying {
playerState.isPlaying = true
for buffer in playerState.buffers {
audioCallback(playerState, aq: playerState.queue, buffer: buffer)
}
AudioQueueStart(playerState.queue, nil)
}
}
您还需要更新代码,以便每次从网络接收数据包时,playerState.packetsWritten
都会递增,同样,当您将数据包添加到音频队列时,playerState.packetsRead
也是如此。kNumPacketsToBuffer
的最佳数量取决于编解码器和网络条件。我建议将 256 用于 AAC 并根据性能向上/向下调整。