入队数据包延迟时,IOS AudioQueue 不播放
Posted
技术标签:
【中文标题】入队数据包延迟时,IOS AudioQueue 不播放【英文标题】:IOS AudioQueue doesnt play when enqueue packets late 【发布时间】:2016-03-16 18:30:05 【问题描述】:我有一个将数据包排队到 AudioQueue 的应用程序,它运行良好。问题是当我在网络中出现延迟时,我无法及时向 AudioQueue 提供数据包。
所有应用程序运行良好,enqueueBuffer 没有返回任何错误,但 AudioQueue 正在丢弃数据包(所以我没有声音),因为它们太旧了。
我可以强制 AudioQueue 播放那些音频包吗?或者至少,知道这些包被丢弃了吗?因为如果我知道的话,我可以做 Pause-Play 来重新启动队列......(不是很好的解决方案,但我没有更好的解决方案)
因为延迟可能很大,我不能使用大缓冲区,因为这样可以减少错误,但不能解决它
非常感谢
【问题讨论】:
【参考方案1】:你在正确的轨道上。当您到达网络缓冲区的末尾时,您可以通过在回调过程中检测,然后暂停 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 并根据性能向上/向下调整。
【讨论】:
非常感谢。那是非常有用的信息。如果我可以强制播放所有数据包(完全不丢弃),那就太好了。但至少,这是个好主意。 暂停队列不会导致数据包被丢弃。音频队列维护一个内部时间线(您可以使用AudioQueueGetCurrentTime:
检索),即使没有任何数据包正在播放,它也会继续前进。当您将包含比当前时间更早的数据包的缓冲区排入队列时,这些数据包将被丢弃。暂停队列也会暂停时间线,因此如果您在数据包用完之前暂停,然后在收到延迟的数据包后恢复播放,这些数据包不会被视为旧数据包,并且会正确播放。以上是关于入队数据包延迟时,IOS AudioQueue 不播放的主要内容,如果未能解决你的问题,请参考以下文章