使用后移除AVAudioPlayerNode导致崩溃问题

5
我正在使用AVAudioEngine播放声音文件并记录输出到文件。我有很多声音效果文件,每个文件都通过点击按钮来播放。为了播放文件,我创建了一个AVAudioPlayerNode并将其连接到引擎。在文件播放完成后,我尝试在 completionHandler 闭包中断开/分离节点以释放内存。如果我不移除节点,我将继续向引擎添加新的节点和新的连接。

然而,下次我尝试播放文件时,应用程序会冻结。这是我的代码:

let url = NSBundle.mainBundle().URLForResource(name, withExtension: "wav")!
let audioPlayerFile = try AVAudioFile(forReading: url)
let playerNode = AVAudioPlayerNode()
self.engine.attachNode(playerNode)
self.engine.connect(playerNode, to: self.engine.mainMixerNode, format: audioPlayerFile.processingFormat)
playerNode.scheduleFile(audioPlayerFile, atTime: nil, completionHandler: { () -> Void in
    self.engine.disconnectNodeOutput(playerNode)
    self.engine.detachNode(playerNode)
})
playerNode.play()

如何实现类似这样的功能,即播放多个文件,在录制时可能会重叠?

1个回答

2

我曾经遇到过类似的问题。我发现在后台线程上分离节点可以防止应用程序冻结。

    playerNode.scheduleBuffer(buffer, atTime: nil, options: nil) { () -> Void in
        self.detach(playerNode)
    }

以下是该方法:

    func detach(player: AVAudioPlayerNode) {
        let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
        dispatch_async(dispatch_get_global_queue(priority, 0)) { () -> Void in
            self.engine.detachNode(player)
    }

然而,我仍然不确定这是否是一个解决方案,因为这些后台线程可能在没有我的知识的情况下无限旋转。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接