Ios AVplayer在来电后恢复

Ios AVplayer在来电后恢复,ios,ios7,avplayer,avplayerlayer,Ios,Ios7,Avplayer,Avplayerlayer,我正在使用AVPlayer播放音乐。我的问题是,接到来电后,播放机无法恢复。当来电时,我如何处理此问题?当中断开始和结束时,音频会话将发送通知。看 从iOS 6开始,您必须处理AVAudioSessionInterruptionNotification和AVAudioSessionMediaServicesWereResetNotification,在此之前,您必须使用委托方法 首先,您应该调用AVAudioSession singleton并将其配置为所需的用途 例如: AVAudioSess

我正在使用
AVPlayer
播放音乐。我的问题是,接到来电后,播放机无法恢复。当来电时,我如何处理此问题?

当中断开始和结束时,音频会话将发送通知。看


从iOS 6开始,您必须处理
AVAudioSessionInterruptionNotification
AVAudioSessionMediaServicesWereResetNotification
,在此之前,您必须使用委托方法

首先,您应该调用AVAudioSession singleton并将其配置为所需的用途

例如:

AVAudioSession *aSession = [AVAudioSession sharedInstance];
[aSession setCategory:AVAudioSessionCategoryPlayback
          withOptions:AVAudioSessionCategoryOptionAllowBluetooth 
                error:&error];
[aSession setMode:AVAudioSessionModeDefault error:&error];
[aSession setActive: YES error: &error];
然后,您应该为AVAudioSession将调用的通知实现两种方法:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(handleAudioSessionInterruption:)
                                             name:AVAudioSessionInterruptionNotification
                                           object:aSession];
第一种是针对因来电、闹钟等而被呼叫的任何中断

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(handleMediaServicesReset)
                                             name:AVAudioSessionMediaServicesWereResetNotification
                                           object:aSession];
第二个问题如果媒体服务器因任何原因重置,您应该处理此通知以重新配置音频或进行任何整理。顺便说一下,通知字典不会包含任何对象

以下是处理回放中断的示例:

- (void)handleAudioSessionInterruption:(NSNotification*)notification {

    NSNumber *interruptionType = [[notification userInfo] objectForKey:AVAudioSessionInterruptionTypeKey];
    NSNumber *interruptionOption = [[notification userInfo] objectForKey:AVAudioSessionInterruptionOptionKey];

    switch (interruptionType.unsignedIntegerValue) {
        case AVAudioSessionInterruptionTypeBegan:{
            // • Audio has stopped, already inactive
            // • Change state of UI, etc., to reflect non-playing state
        } break;
        case AVAudioSessionInterruptionTypeEnded:{
            // • Make session active
            // • Update user interface
            // • AVAudioSessionInterruptionOptionShouldResume option
            if (interruptionOption.unsignedIntegerValue == AVAudioSessionInterruptionOptionShouldResume) {
                // Here you should continue playback.
                [player play];
            }
        } break;
        default:
            break;
    }
}
请注意,当可选值为
avaudiosessioninterruptionoptions shouldResume

对于其他通知,您应注意以下事项:

- (void)handleMediaServicesReset {
// • No userInfo dictionary for this notification
// • Audio streaming objects are invalidated (zombies)
// • Handle this notification by fully reconfiguring audio
}

问候。

在某些情况下,即使我调用
play()
,我的
AVPlayer
也不会继续播放。只有重新加载播放器可以帮助我解决问题:

    func interruptionNotification(_ notification: Notification) {
    guard let type = notification.userInfo?[AVAudioSessionInterruptionTypeKey] as? UInt,
      let interruption = AVAudioSessionInterruptionType(rawValue: type) else {
        return
    }
    if interruption == .ended && playerWasPlayingBeforeInterruption {
      player.replaceCurrentItem(with: AVPlayerItem(url: radioStation.url))
      play()
    }
  }

我得等2秒钟才能让它工作

        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {

            self.player.play()
        }
整个职能:

func playerInterruption(notification: NSNotification) {

    guard let userInfo = notification.userInfo,
        let typeValue = userInfo[AVAudioSessionInterruptionTypeKey] as? UInt,
        let type = AVAudioSessionInterruptionType(rawValue: typeValue) else {
            return
    }
    if type == .began {
        // Interruption began, take appropriate actions (save state, update user interface)
        player.pause()
    }
    else if type == .ended {

        guard let optionsValue =
            userInfo[AVAudioSessionInterruptionOptionKey] as? UInt else {

                return
        }
        let options = AVAudioSessionInterruptionOptions(rawValue: optionsValue)
        if options.contains(.shouldResume) {
            // Interruption Ended - playback should resume

            DispatchQueue.main.asyncAfter(deadline: .now() + 2) {

                self.player.play()
            }

        }
    }
}

我在“AVAudioPlayer”控制器中遇到了同样的问题。使用“AVAudioSession.interruptionNotification”,我们可以在中断结束后恢复音频播放,即使音频在后台播放

    @objc func interruptionNotification(notification: Notification) {
    guard let type = notification.userInfo?[AVAudioSessionInterruptionTypeKey] as? UInt,
        let interruption = AVAudioSession.InterruptionType(rawValue: type) else {
            return
    }

    if interruption == .began{
        print("Pause audio....")
        self.player?.pause()
        do {
            try AVAudioSession.sharedInstance().setActive(false)
            print("AVAudioSession is inactive")
        } catch let error as NSError {
            print(error.localizedDescription)
        }
    }

    if interruption == .ended{
        print("Play audio....")
        do {
            try AVAudioSession.sharedInstance().setActive(true)
            print("AVAudioSession is Active again")
            self.player?.play()
        } catch let error as NSError {
            print(error.localizedDescription)
        }
    }
}

在这里,首先需要在中断时禁用AVAudioSession,在中断结束后激活AVAudioSession。它工作得很好,请试一试

各位读者好。想与
AVAudioSessionInterruptionNotification
分享我的经验吗。这让我发疯。我花了一天时间来寻找解决办法。我尝试了上面写的所有东西,但没有任何帮助。iOS 13.2.3。因此,由于某些原因,此通知无法与
AVAudioSessionCategoryPlayback
一起正常工作。对我来说,修复方法就是将其替换为
AVAudioSessionCategoryPlayAndRecord
,我开始收到
avaudiosessioninterruptiontyped
请参见下面的示例:

-(void)setupAudioSession {

    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
    [[AVAudioSession sharedInstance] setMode:AVAudioSessionModeDefault error:nil];
    [[AVAudioSession sharedInstance] setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];    
}
之后,注册您的观察者,如下所示:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioSessionHandleIntrruption:) name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]];
并实际实施中断方法:

- (void)audioSessionHandleIntrruption:(NSNotification *)notification {

    NSDictionary *userInfo = notification.userInfo;
    int interruptionType = [userInfo[AVAudioSessionInterruptionTypeKey] intValue];

    if (interruptionType == AVAudioSessionInterruptionTypeBegan) {
        //Interruption begun

    } else if (interruptionType == AVAudioSessionInterruptionTypeEnded) {
        int interruptionOption = [userInfo[AVAudioSessionInterruptionOptionKey] intValue];

        BOOL shouldResumePlayback = interruptionOption == AVAudioSessionInterruptionOptionShouldResume;

        if (shouldResumePlayback) {
            //Resume playback if needed
        }
    }
}

希望这能为别人节省很多时间

我们可以使用CTCallCenter吗?我不建议使用CTCallCenter,因为AVAudioSession提供了更详细的界面。我更新了答案以删除不推荐的方法。在文档中,在处理MediaServicesWereReset时,说明了“采取适当的步骤重新初始化应用程序使用的任何音频对象”。。只是重新配置音频会话并将其设置回活动状态。还有什么我该做的吗?太棒了!!这真的对我有用!谢谢你帮我节省时间
- (void)audioSessionHandleIntrruption:(NSNotification *)notification {

    NSDictionary *userInfo = notification.userInfo;
    int interruptionType = [userInfo[AVAudioSessionInterruptionTypeKey] intValue];

    if (interruptionType == AVAudioSessionInterruptionTypeBegan) {
        //Interruption begun

    } else if (interruptionType == AVAudioSessionInterruptionTypeEnded) {
        int interruptionOption = [userInfo[AVAudioSessionInterruptionOptionKey] intValue];

        BOOL shouldResumePlayback = interruptionOption == AVAudioSessionInterruptionOptionShouldResume;

        if (shouldResumePlayback) {
            //Resume playback if needed
        }
    }
}