【发布时间】:2019-07-18 15:03:33
【问题描述】:
我有使用 AVAudioEngine 播放音频的 iOS 应用程序。我将 AudioFile 中的帧读入 AVAudioPCMBuffer,然后将缓冲区发布到 AVAudioPlayerNode.scheduleBuffer。我在 DispatchQueue 上阅读了帧。我遇到的问题是,当应用程序有很多其他工作要做 - 与服务器同步和下载文件时,DispatchQueue 上的读取帧会延迟几秒钟执行,这会导致声音中断。 我已将 DispatchQueueQos 设置为尽可能高的 .userInteractive,并且我在应用程序中没有其他具有相同 qos 的队列,但有时仍需要几秒钟才能在该队列上执行代码。
有解决办法吗?有什么方法可以告诉操作系统这个队列是用于音频或类似的吗?
注意:如果应用程序运行一些繁重的后台操作,我不会遇到 AVPlayer 的这个问题。
编辑:一些代码以便更好地理解。问题是有时在队列中发布任务需要几秒钟(从评论 1 到评论 2)。
var audioProcessingQueue = DispatchQueue(label: "audioProcessing", qos: .userInteractive)
var player = AVAudioPlayerNode()
//comment 1
self.audioProcessingQueue.async(flags: .barrier) {
//comment 2
//some buffer processing here...
player.scheduleBuffer(buffer, at: nil)
}
谢谢
【问题讨论】:
-
与服务器同步和下载文件应该通过异步调用来完成。网络不是你想在主线程上做的事情。主线程基本上是用于 UI 的东西。确保调度队列 main 中没有包含任何网络调用。
-
你能分享一些代码sn-ps吗?
-
它没有做任何文件下载或类似的事情。我添加了代码以便更好地理解
-
在 Instruments 下运行它,看看是什么阻碍了您的队列(请参阅系统跟踪模板作为起点)。我不为此推荐
.userInteractive;它应该是.userInitiated。 QoS 不仅仅意味着优先级;它还有其他不明显的影响。使用符合您意图的优先级。为什么要在这里添加障碍?这个队列上还有什么(应该是串行队列吗?)如果您删除处理并按原样安排缓冲区会发生什么?
标签: ios swift avaudioengine avaudioplayernode