15

我有以下代码(重新)开始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

4

2 回答 2

5

Xcode 版本 9.2 (9C40b) + Swift 4 :我知道这个问题有点老了,但是,audioEngine.start()即使在 do/try/catch 中,我也遇到了同样的崩溃问题,并且还从 Crashalytics 收到以下内容:

致命异常:com.apple.coreaudio.avfaudio 错误 561015905

S1LENT WARRIOR 的 sleep(1) “hack”在某些情况下有效,但不是全部(特别是 AVAudioEngineConfigurationChangeNotification 选择器)。

最后,我使用 Obj-C 异常处理来真正捕获错误,因此不会发生崩溃,来自 freytag 的这篇非常有用的帖子(非常感谢!):

在 Swift 中捕获 NSException

现在,在实现 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:Initialize: (inputNode != nullptr || outputNode != nullptr)] 发生错误:Error Domain=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()函数包装它,并取消所有有用的功能...... doh。

于 2018-01-06T03:10:38.037 回答
4

AVAudioSessionInterruption我在处理通知时遇到了同样的错误。就我而言,当我在中断结束后
尝试开始时出现错误。 经过一段时间的详细测试和调试,我注意到如果我引入before或. 所以我之前添加了,我的应用程序停止崩溃! AVAudioEngine
debugger breakpointaudioEngine.prepare()audioEngine.start()
sleep(1)audioEngine.start()

我知道这不是一个非常优雅的解决方案,但仍然希望这对其他人有帮助!

于 2016-10-08T20:06:26.770 回答