Сбой в AVAudioEngine.start(), даже если он заключен в do/catch

У меня есть следующий код для (повторного) запуска AVAudioEngine, подключенного к AVAudioEngineConfigurationChangeNotification:

   do {
       try self.engine.start()
   } catch {
       DDLogError("could not start sound engine")
       self.soundEnabled = false
       return
   }

self.engine определяется как

private let engine = AVAudioEngine()

Однако я часто получаю отчеты о сбоях через Crashlytics, в которых говорится:

Фатальное исключение: ошибка com.apple.coreaudio.avfaudio 561015905

в строке, содержащей try self.engine.start().

561015905 — это AVAudioSessionErrorCodeCannotStartPlaying, и насколько я понимаю, это должен быть код ошибки NSError, а не исключение, которое должно быть перехвачено моим пустым catch в приведенном выше коде. Тем не менее, приложение просто вылетает в этот момент. Что мне не хватает?

Я знаю, что бывают ситуации, когда приложение просыпается в фоновом режиме, когда может возникнуть эта ошибка, и меня это устраивает, если я могу каким-то образом поймать это, как я думал, что смогу с do/catch.


person Mike    schedule 14.12.2015    source источник
comment
Я получаю аналогичную ошибку. Вы поняли, почему это произошло?   -  person Pulsar    schedule 12.02.2016
comment
Нет. Я отправил отчет об ошибке в Apple, но еще не получил ответа. Тем временем я перестал использовать AVAudioEngine.   -  person Mike    schedule 13.02.2016
comment
@Mike есть новости по этому поводу? Вы нашли лучший обходной путь, чем sleep()? И вы вообще слышали об Apple? Судя по всему, это все еще проблема в iOS 11.   -  person Ryan Poolos    schedule 26.07.2017
comment
Как я уже сказал, мы перестали использовать AVAudioEngine из-за этой ошибки. С тех пор Apple попросила нас воспроизвести ошибку с более новыми версиями iOS (и автоматическое сообщение, отправленное в открытые отчеты при выпуске новых версий SDK), но, поскольку проблема нас больше не интересует, мы этого не сделали. Это означает, что если вам все еще не все равно, вам, вероятно, следует открыть свой собственный отчет об ошибке. Извините, я не мог больше помочь, удачи в решении этой проблемы. Если вы когда-нибудь это сделаете, я хотел бы услышать ответ!   -  person Mike    schedule 27.07.2017


Ответы (2)


Xcode Version 9.2 (9C40b) + Swift 4: я знаю, что этот вопрос немного устарел, однако у меня были те же проблемы со сбоями с audioEngine.start(), хотя в do/try/catch я также получил следующее от Crashalytics:

Фатальное исключение: ошибка com.apple.coreaudio.avfaudio 561015905

«Хак» сна S1LENT WARRIOR (1) работал в некоторых случаях, но не во всех (в частности, с селектором AVAudioEngineConfigurationChangeNotification).

Наконец, я использовал обработку исключений Obj-C, чтобы действительно поймать ошибку, чтобы не произошло сбоя, из этого очень полезного поста от freytag (большое спасибо!):

Перехват NSException в Swift

Теперь, после реализации файлов ObjC .h и .m и связующего заголовка, я делаю:

do {
    try ObjC.catchException {
        try! self.audioEngine.start()
    }
}
catch {
    print("An error occurred: \(error)")
}

Вы можете проверить это, испортив инициализацию движка (например, ничего не .attach или .connect) и без сбоя... только:

2018-01-06 10:01:48.890801+0700 XXXXXX[16389:3367770] [avae] AVAEInternal.h:70:_AVAE_Check: обязательное условие ложно: [AVAudioEngineGraph.mm:1209:Инициализировать: (inputNode != nullptr || outputNode != nullptr)] Произошла ошибка: Домен ошибки = com.apple.coreaudio.avfaudio Code = 0 "(null)"

Перед использованием убедитесь, что audioEngine запущен, например:

func play(soundName: String) {
    if !audioEngine.isRunning {
        return
    }
    // play sound
 }

Итак, у вас нет звука, но это «изящный сбой».

Кажется нелепым, что в Swift вы не можете правильно перехватить исключение, и хорошо, если вы собираетесь сделать некоторые исключения неперехватываемыми, тогда, по крайней мере, сначала предоставьте метод для тестирования, что-то вроде audioEngine.areYouConfiguredProperly(). О, подождите, есть этот метод (в Obj-C) [AVAudioEngine startAndReturnError:], но кто-то решил обернуть его функцией startEngine() и покончить со всеми полезными функциями... дох.

person Christian Cerri    schedule 06.01.2018

Я столкнулся с той же ошибкой при обработке уведомления AVAudioSessionInterruption.
В моем случае ошибка возникала, когда я пытался запустить AVAudioEngine после прекращения прерывания.
После тщательного тестирования и отладки в течение некоторого времени я заметил, что приложение не работает. не произойдет сбой, если я введу debugger breakpoint перед audioEngine.prepare() или audioEngine.start().
Итак, я добавил sleep(1) перед audioEngine.start(), и мое приложение перестало падать!

Я знаю, что это не очень элегантное решение, но все же надеюсь, что это может помочь кому-то еще!

person S1LENT WARRIOR    schedule 08.10.2016