iOS8 AVAudioSession setActive ошибка

Я тестирую свое приложение в XCode 6 и обнаруживаю проблему с AVAudioSession в iOS8.

Когда я звоню

[[AVAudioSession sharedInstance] setActive: НЕТ ошибки: ноль];

Я получаю следующее сообщение об ошибке:

AVAudioSession.mm:623: -[AVAudioSession setActive:withOptions:error:]: деактивация аудиосеанса с работающим вводом-выводом. Все операции ввода-вывода должны быть остановлены или приостановлены перед деактивацией аудиосеанса.

В AVAudioSession.h говорится

Обратите внимание, что этот метод вызовет исключение в приложениях, связанных с iOS 8 или более поздней версии, если сеанс установлен в неактивное состояние, когда в нем выполняются или приостановлены операции ввода-вывода (например, аудиоочереди, проигрыватели, записывающие устройства, преобразователи, удаленные операции ввода-вывода и т. д.). .

Но я не уверен, как я могу проверить, работает ли ввод-вывод, и как я могу избавиться от всего, когда мне нужно сбросить аудиосеанс.


person xialin    schedule 09.06.2014    source источник
comment
Можете ли вы объяснить контекст и привести пример использования, почему вы хотите проверить, выполняется ли ввод-вывод?   -  person vladof81    schedule 02.07.2014
comment
@vladof Если такой ошибки нет, мне не нужно проверять работающий ввод-вывод. Итак, ситуация такова, что я хочу убедиться, что при вызове setActive:NO нет запущенного ввода-вывода.   -  person xialin    schedule 03.07.2014
comment
@Anton не исправление, но я обнаружил, что другая библиотека, которую я использую - pjsip - управляет запуском / остановкой аудиосессии на более низком уровне. Итак, я справляюсь с этим, избегая вызова setActive, если я знаю, что аудиосеанс уже настроен. Это как раз мой случай. Вы должны выяснить, есть ли что-то еще, что разделяет аудиосессию с вашим приложением.   -  person xialin    schedule 25.09.2014


Ответы (5)


Я решил эту проблему, вставив этот код в метод AVAudioPlayerDelegate.

-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
  [audioPlayer stop];
  [audioPlayer prepareToPlay];
}

где audioPlayer — это переменная, объявленная в заголовке моего класса.

инструкция prepareToPlay должна решить вашу проблему!

person Alessio Campanelli    schedule 09.10.2014
comment
@d4Rk это делает для меня на iOS 9.3: [audioPlayer stop]; [audioPlayer prepareToPlay]; [[AVAudioSession sharedInstance] setActive:NO error:nil]; - person Alejandro Iván; 07.07.2016
comment
в моем случае такая же ошибка возникает для видеоплеера (AVPlayer), у которого вообще нет этих методов - person Vyachaslav Gerchicov; 04.05.2019

Имейте в виду. Если вы воспроизводите фильм (даже без звука и с удаленной звуковой дорожкой), он все равно будет создавать поток ввода-вывода, который всегда будет вызывать указанную выше ошибку.

person Aggressor    schedule 17.03.2016

Я использую AVAudioEngine и AVAudioPlayerNode для воспроизведения звуков. Я встречаю ту же проблему. Моя среда — iOS 10.

Я использую AVAudioSession.sharedInstance() для обработки AVAudioSession. Когда я запускаю свое приложение в симуляторе, все в порядке, но когда я переключаю его на свое устройство. Это не удалось.

Я полагаю, что использую один и тот же сеанс для обработки записи и воспроизведения. Так что это может вызвать некоторые странные проблемы. В моем случае я записываю звук и задержу 1 с, чтобы воспроизвести его. Поэтому, когда я использую stopRecordingAudio(), я добавляю этот фрагмент кода:

if audioEngine.running {
    audioEngine = AVAudioEngine() // var audioEngine = AVAudioEngine()
    try! AVAudioSession.sharedInstance().setActive(false)
}

После переопределения audioEngine, audioEngine был вынужден остановиться, и сессия была освобождена. Катастрофа больше не повторялась.

Надеюсь, это сообщение поможет вам.

person CashLee李秉骏    schedule 24.10.2016

Swift 5, iOS 12

Я использую AVPlayer, в нем нет метода prepareToPlay. Поэтому ответ Алессио Кампанелли не решает мою проблему. Но я заметил следующее

player.pause()

print("currentTime:",  player.currentTime().seconds) //currentTime: 4.258164744
print("status:", player.status.rawValue) //status: 1 (readyToPlay)
print("timeControlStatus:", player.timeControlStatus.rawValue) //timeControlStatus: 0 (paused)
print("rate:", player.rate) //rate: 0.0

sleep(1)

print("currentTime:",  player.currentTime().seconds) //currentTime: 4.261325767
print("status:", player.status.rawValue) //status: 1 (readyToPlay)
print("timeControlStatus:", player.timeControlStatus.rawValue) //timeControlStatus: 0 (paused)
print("rate:", player.rate) //rate: 0.0

После вызова метода pause проигрыватель некоторое время воспроизводит аудиофайл. Хотя другие свойства говорят, что он в паузе. Итак, единственное решение, которое я нашел, это

player.pause()
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
    do {
        try AVAudioSession.sharedInstance().setActive(false)
    } catch let error {
        print(error)
    }
}

На самом деле достаточно даже 0,1 секунды. Это плохой способ, но я не смог найти ничего лучше. Если кто знает, как проверить, когда проигрыватель перестает воспроизводить аудиофайл, дайте знать.

person Iaenhaall    schedule 18.06.2019

Я приостановил работу My AVplayer до того, как AVAudioSession setActive NO;

[self.audioPlayer pause]; [[AVAudioSession sharedInstance] setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];

person Trouble maker    schedule 17.11.2015