Прерывания AVAudioSession и изменения маршрута

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

class AudioMultiTrack {

var tracks     : [AudioTrack]
var mixer      : AVAudioMixerNode
var pauseTime  : AVAudioTime?

var engine     = AVAudioEngine()
var volumes    = [Float]()

init(audioTracks: [AudioTrack]){
    tracks = audioTracks
    mixer = engine.mainMixerNode
}

func initialize() {
    for track in tracks {
        track.setUpTrack()
        engine.attach(track.audioPlayer)
        engine.connect(track.audioPlayer, to: mixer, format: track.format)
        track.scheduleFile()
    }

    do {
        try engine.start()
    } catch {
        fatalError("error starting engine")
    }
}

func play() {
    for track in tracks {
        track.audioPlayer.play(at: startTime())
    }
}

func pause() {
    pauseTime = tracks[0].audioPlayer.lastRenderTime

    for track in tracks {
        track.audioPlayer.pause()
    }

}

func unPause() {

    for track in tracks {
        track.scheduleFile()
        track.audioPlayer.play(at: pauseTime)
    }
}

func stop() {
    pauseTime = tracks[0].audioPlayer.lastRenderTime
    engine.stop()

    for track in tracks {
        engine.detach(track.audioPlayer)
    }

    engine.reset()
}

func startTime() ->AVAudioTime {
    let sampleRate = tracks[0].format.sampleRate
    let sampleTime = AVAudioFramePosition(sampleRate)

    return AVAudioTime(sampleTime: sampleTime, atRate: sampleRate)
}

При нажатии на паузу в GameViewController:

func pausePressed() {
   audio.pause()
}

func continuePressed() {
   audio.unPause()
}

Однако при работе с прерываниями или изменениями маршрута следующим образом:

    func handleInterruption(notification: NSNotification) {
    guard let info = notification.userInfo else { return }

    switch info[AVAudioSessionInterruptionTypeKey] as! Int {
    case 0:
        audio.unPause()
    case 1:
        audio.pause()
    default:
        break;
    }
}

Программа вылетает, и я получаю:

*** Завершение работы приложения из-за необработанного исключения "com.apple.coreaudio.avfaudio", причина: "необходимое условие ложно: _engine->IsRunning()"

Итак, похоже, что звуковой движок останавливается, и я не хочу повторно инициализировать аудиоплеер по ряду причин, включая время установки и непрерывность игры...

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


person derekFairholm    schedule 14.02.2017    source источник


Ответы (1)


Я не думаю, что это возможно, потому что вы создаете аудиоплеер для каждого звука, его нужно подготовить, настроить оборудование и т. д. Когда звук будет завершен, эта настройка будет удалена, и ее нужно будет выполнить снова. т.е. вероятно, невозможно поддерживать звуковой движок «работающим».

person StackUnderflow    schedule 17.02.2017