AVAudioEngine.start()中出现崩溃,即使它被包含在do/catch块中

16

我有以下代码用于(重新)启动已连接到AVAudioEngineConfigurationChangeNotificationAVAudioEngine:

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

self.engine被定义为

private let engine = AVAudioEngine()

然而,我经常通过Crashlytics收到崩溃报告,内容为:

Fatal Exception: com.apple.coreaudio.avfaudio error 561015905

在包含try self.engine.start()的那一行发生了错误。

561015905是AVAudioSessionErrorCodeCannotStartPlaying,根据我的理解,这应该是一个NSError错误代码,而不是一个异常,应该被上面代码中的空白catch捕获。但是,应用程序似乎在那一点上仍会崩溃。我错过了什么?

我知道有些情况下,应用程序在后台唤醒时可能会出现此错误,只要我能够捕获它的发生,就可以了,因为我认为我可以使用do/catch来实现这一点。


1
我遇到了类似的错误。你弄清楚这是为什么了吗? - Binary Pulsar
1
不,我已经向苹果提交了一个错误报告,但还没有收到回复。与此同时,我停止使用 AVAudioEngine - Mike
@Mike,这个问题有什么更新吗?你有没有找到比sleep()更好的解决方法?还有,你有没有收到苹果方面的回复?从看起来来看,在iOS 11中这仍然是一个问题。 - Ryan Poolos
1
正如我之前所说,由于这个 bug,我们已经停止使用 AVAudioEngine。自那以后,苹果公司要求我们使用更新的 iOS 版本来重现该 bug(当新的 SDK 版本发布时,会发送自动化消息以打开报告),但由于这个问题对我们来说已经不再重要,所以我们没有这样做。也就是说,如果你仍然关心这个问题,你应该自己打开一个 bug 报告。很抱歉我不能提供更多帮助,祝你好运解决这个问题。如果你最终解决了它,我很想听到你的回音! - Mike
2个回答

6
Xcode版本9.2(9C40b)+ Swift 4:我知道这个问题有点老,但是,即使在do/try/catch中,使用时仍然会遇到崩溃问题,并收到来自Crashalytics的以下信息:
致命异常:com.apple.coreaudio.avfaudio错误561015905
S1LENT WARRIOR的sleep(1)“hack”在某些情况下有效,但不是所有情况(特别是使用AVAudioEngineConfigurationChangeNotification选择器)。
最终,我使用了Obj-C异常处理来真正捕获错误,以便不会发生崩溃,这是由freytag发布的非常有用的文章(非常感谢!): Catching NSException in Swift 现在,在实现ObjC .h和.m文件和桥接头文件后,我执行以下操作:
do {
    try ObjC.catchException {
        try! self.audioEngine.start()
    }
}
catch {
    print("An error occurred: \(error)")
}

你可以通过损坏引擎初始化(例如不连接或不附加任何东西)来测试它,而不会崩溃,只有以下内容:
2018-01-06 10:01:48.890801+0700 XXXXXX[16389:3367770] [avae] AVAEInternal.h:70:_AVAE_Check: required condition is false: [AVAudioEngineGraph.mm:1209:Initialize: (inputNode != nullptr || outputNode != nullptr)] An error occurred: 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()函数包装它并放弃所有有用的功能...失误。


5
当我处理`AVAudioSessionInterruption`通知时,遇到了同样的错误。在我的情况下,当中断结束后尝试启动`AVAudioEngine`时出现了错误。
经过详细的测试和调试一段时间后,我发现如果在`audioEngine.prepare()`或`audioEngine.start()`之前引入一个`debugger breakpoint`,应用程序不会崩溃。
因此,在`audioEngine.start()`之前加入了`sleep(1)`,我的应用程序停止崩溃!

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接