【问题标题】:Removing AVAudioPlayerNode after use causes crash使用后删除 AVAudioPlayerNode 会导致崩溃
【发布时间】:2015-12-04 12:55:11
【问题描述】:

我正在使用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()

实现此类功能的最佳方式是什么,即在录制时播放多个文件,可能会相互重叠?

【问题讨论】:

    标签: ios avaudioengine


    【解决方案1】:

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

        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)
        }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多