iOS AVPlayer 来电、闹钟和更改外设的处理办法

我们在开发中使用avplayer播放时经常会遇到诸如来电、闹钟响了或者插拔耳机等影响因素,这些事件处理不好会造成不好的用户体验。所以今天我们来一起简单的解决一下这些问题。

首先我们需要注册通知来监听这些事件。

    //监听打电话等打断
    [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(interruptionComing:)
                                                     name:AVAudioSessionInterruptionNotification
                                                   object:nil];
    //耳机插入等外设改变
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioSessionRouteChange:) name:AVAudioSessionRouteChangeNotification object:nil];

//swift
    NotificationCenter.default.addObserver(self, selector: #selector(interruptionComing(notification:)), name: AVAudioSession.interruptionNotification, object: nil)
        
    NotificationCenter.default.addObserver(self, selector: #selector(audioSessionRouteChange(notification:)), name: AVAudioSession.routeChangeNotification, object: nil)

处理来电、闹铃打断播放通知

- (void)interruptionComing:(NSNotification *)notification {
    NSDictionary *userInfo = notification.userInfo;
    AVAudioSessionInterruptionType type = [[userInfo valueForKey:AVAudioSessionInterruptionTypeKey] integerValue];
    if (type == AVAudioSessionInterruptionTypeBegan) {
        NSLog(@"来电闹钟暂停");
        [self.player pause];
    }
    if (type == AVAudioSessionInterruptionTypeEnded) {
        NSLog(@"结束继续播放");
        [self.player play];
    }
}

//swift
    @objc private func interruptionComing(notification: Notification) {
        let typeValue = notification.userInfo?[AVAudioSessionInterruptionTypeKey]
        let type = AVAudioSession.InterruptionType(rawValue: typeValue as! UInt)
        if type == .began {
            self.player.pause()
        }
        if type == .ended {
            self.player.play()
        }

处理外设改变

- (void)audioSessionRouteChange:(NSNotification *)notify {
    NSDictionary *userInfo = notify.userInfo;
    NSInteger routeChangeReason = [[userInfo valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
    switch (routeChangeReason) {
        case AVAudioSessionRouteChangeReasonNewDeviceAvailable:
            NSLog(@"耳机插入");
            // 继续播放音频,什么也不用做
            break;
        case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:
            NSLog(@"耳机拔出");
            // 注意:拔出耳机时系统会自动暂停你正在播放的音频,因此只需要改变UI为暂停状态即可
            if (self.playStatusType == HXPlayStatusTypePlay) {
                [self.player pause];
            }
            break;
        default:
            break;
    }
}

//swift
    @objc private func audioSessionRouteChange(notification: Notification) {
        guard let userInfo = notification.userInfo,
                        let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt,
                        let reason = AVAudioSession.RouteChangeReason(rawValue:reasonValue) else {
                            return
                    }
        switch reason {
        case .newDeviceAvailable:
            print("继续播放")
            break
            
        case .oldDeviceUnavailable:
            self.player.pause()
            break
        default:
        break
        }
    }

最后要记得remove掉注册的通知哦

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self name:AVAudioSessionInterruptionNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:AVAudioSessionRouteChangeNotification object:nil];
}

//swift
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。