iOS AVAudioSession 中断通知未按预期工作

iOS AVAudioSession interruption notification not working as expected

我想知道我的 AVAudioRecorder 何时无法访问(例如音乐开始播放时)。

因为 audioRecorderEndInterruption 将被 iOS 弃用 9 我正在关注 AVAudioSession 的中断通知(但两者都没有按预期工作)。

问题是,如果应用程序在中断发生时一直在前台运行并且一直保持在前台,则永远不会调用中断通知。

例如:用户在没有将应用程序移至后台的情况下开始和停止播放音乐。

要检测我正在使用的任何中断:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioSessionWasInterrupted:) name:AVAudioSessionInterruptionNotification object:nil];
...
- (void)audioSessionWasInterrupted:(NSNotification *)notification {
    if ([notification.name isEqualToString:AVAudioSessionInterruptionNotification]) {
        NSLog(@"Interruption notification");

        if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeBegan]]) {
            NSLog(@"InterruptionTypeBegan");
        } else {
            NSLog(@"InterruptionTypeEnded");
        }
    }
}

我得到了预期的 InterruptionTypeBegan,但是如果应用程序仍在前台,则不会调用 InterruptionTypeEnded(这意味着它不会被调用,直到应用程序被放置在后台并且回到前台)。

当应用程序在前台时发生中断,我如何收到 InterruptionTypeEnded 通知?

如果您还没有设置,请尝试将 AVCaptureSession 的 属性 usesApplicationAudioSession 设置为 NO

This 如果您正在寻找更多详细信息,问答可以作为很好的参考。

我尝试了这个,发现 InterruptionTypeEnded 可能会在某些应用程序的音乐暂停后调用,但其他应用程序在暂停时不会调用。

我的解决方案是更新 UI 让用户知道记录已停止并做一些相关工作,例如文件操作。当中断结束时,激活AVAudioSession,如果没有错误,开始新的记录。

如果你想加入中断前后的文件,这个问题的答案:AVAudioRecorder records only the audio after interruption可能对你有帮助。

这是一个普遍存在的问题,影响任何使用 AV 框架组件的应用程序(原生 iOS 应用程序也是如此)。

正如's documentation中关于音频中断的解释,InterruptionTypeEnded实际上应该应用于提到的场景:

If the user dismisses the interruption ... the system invokes your callback method, indicating that the interruption has ended.

但是,它还指出 InterruptionTypeEnded 可能根本不会被调用:

There is no guarantee that a begin interruption will have an end interruption.

因此,在上述场景中需要采用不同的方法。


在处理音乐中断时,这个问题不会持续太久。 iOS 9 有效防止在调用应用程序的音频处理程序时使用外部音频源。

处理媒体中断的确切问题的一种方法可能是收听 MPMusicPlayerControllerplaybackState,如以下 Whosebug 问题所示:Detecting if music is playing?.


处理中断问题的更直接的方法是:

通过在 InterruptionTypeBegan 时重新调用您的音频组件来完全阻止外部音频中断。

或者通过给出 UI 指示表明外部媒体源中断了音频会话(例如显示未激活的麦克风)。


希望  能提出更好的解决方案,但与此同时,这应该会给您一些解决中断问题的选择。