2015-12-04 2 views
3

Я использую AVAudioEngine для воспроизведения звуковых файлов и записи вывода в файл. У меня много файлов звукового эффекта, каждый из которых воспроизводится нажатием кнопки. Чтобы воспроизвести файл, я создаю файл AVAudioPlayerNode и подключаю его к движку. После того, как файл играл, я пытаюсь отключить/отсоединить узел в завершении закрытия Handler, чтобы освободить память. Если я не удаляю узлы, я просто буду добавлять новые узлы и новые подключения к движку.Удаление AVAudioPlayerNode после использования приводит к сбою

Однако в следующий раз, когда я попытаюсь воспроизвести файл, приложение просто зависает. Вот мой код:

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

Какой самый лучший способ реализовать функциональность, как это, то есть играет несколько файлов, потенциально перекрывая друг друга, во время записи?

ответ

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

Однако, я все еще не уверен, что это решение само по себе, потому что эти фоновые потоки могут вращаться бесконечно без моего ведома.

Смежные вопросы