ios - 尝试从后台恢复时触发 AVAudioSessionInterruptionNotification 和 AVAudioSessionInterruptionWasSuspendedKey

标签 ios objective-c avaudioplayer avaudiosession

AVAudioPlayer 在后台播放音频,用户可以通过耳机控件或锁屏控件暂停它。 如果用户在 30 秒内执行此操作并尝试恢复 - 一切正常。 如果用户尝试在超过 30 秒后恢复它 - 音频开始播放,但一秒钟后 AVAudioSessionDelegateaudioSessionInterruptionNotification 被触发,AVAudioSessionInterruptionWasSuspendedKey 是。

之后,应用程序将完全停止对远程控制事件使用react。事件被触发,但 AVAudioPlayer 不响应任何命令。事实上,[[self audioplayer] isAudioPlaying] 在播放继续时返回 NO。

如果我尝试按以下方式处理它 - 它会有所帮助(所以我将 AVAudioSession 设置为不活动,然后 playHelper 方法激活它并播放音频),但是有一个小故障,因为通知在开始播放后被触发.

- (void)audioSessionInterruptionNotification:(NSNotification *)interruption {
    UInt8 interruptionType = [[interruption.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] intValue];

    NSLog(@"Session interrupted > --- %s ---\n", interruptionType == AVAudioSessionInterruptionTypeBegan ? "Begin Interruption" : "End Interruption");
    NSDictionary *notificationUserInfo = [interruption userInfo];
    if (interruptionType == AVAudioSessionInterruptionTypeBegan) {
        if ([notificationUserInfo valueForKey:AVAudioSessionInterruptionWasSuspendedKey]) {
            [[AVAudioSession sharedInstance] setActive:false error:nil];
            [self playHelper];
        } else {
            [self interruptionStarted];
        }
    } else if (interruptionType == AVAudioSessionInterruptionTypeEnded) {
        [self interruptionEnded:(NSUInteger)[notificationUserInfo objectForKey:AVAudioSessionInterruptionOptionKey]];
    }
}

请告知可能导致此问题的原因。

最佳答案

AVAudioSessionInterruptionWasSuspendedKey 通知被抛出,因为只要您的应用进入后台并且没有任何播放,您应该停用 Audio Session 。如果您的播放器在用户从锁定屏幕暂停时正在播放,您不必停用该 session 。

当您的应用程序被发送到后台时,您应该监听通知,当它被激活时,Swift 中的代码应该如下所示。

NotificationCenter.default.addObserver(forName: UIApplication.willResignActiveNotification, object: nil, queue: .main) { sender in
            guard self.player.isPlaying == false else { return }
            self.setSession(active: false)
        }

NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: .main) { sender in
            guard self.player.isPlaying else { return }
            self.setSession(active: true)
        }

    func setSession(active: Bool) -> Bool {
        let session = AVAudioSession.sharedInstance()
        do {
            try session.setCategory(.playback, mode: .default)
            try session.setActive(active)
            return true
        } catch let error {
            print("*** Failed to activate audio session: \(error.localizedDescription)")
            return false
        }
    }

关于ios - 尝试从后台恢复时触发 AVAudioSessionInterruptionNotification 和 AVAudioSessionInterruptionWasSuspendedKey,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57204080/

相关文章:

ios - willMoveToParentViewController 和 didMoveToParentViewController

ios - MKMapView 第一次出现时未正确居中(但此后有效)

iphone - Objective-C "<...>"符号

iphone - 如果打开静音模式如何停止播放声音

iphone - 如何用自身叠加声音?

ios - Objective-C 无法使用 AVAudioPlayer 播放声音

ios - 如何在 Controller 之间传递数据?

ios - UIScrollView subview 放置错误

iphone - 如何将 NSManagedObjects 的 NSArray 转换为 NSData

iphone - becomeFirstResponder 不开火