iOS AVPlayer 來(lái)電、鬧鐘和更改外設(shè)的處理辦法

我們?cè)陂_發(fā)中使用avplayer播放時(shí)經(jīng)常會(huì)遇到諸如來(lái)電、鬧鐘響了或者插拔耳機(jī)等影響因素,這些事件處理不好會(huì)造成不好的用戶體驗(yàn)。所以今天我們來(lái)一起簡(jiǎn)單的解決一下這些問(wèn)題。

首先我們需要注冊(cè)通知來(lái)監(jiān)聽(tīng)這些事件。

    //監(jiān)聽(tīng)打電話等打斷
    [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(interruptionComing:)
                                                     name:AVAudioSessionInterruptionNotification
                                                   object:nil];
    //耳機(jī)插入等外設(shè)改變
    [[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)

處理來(lái)電、鬧鈴打斷播放通知

- (void)interruptionComing:(NSNotification *)notification {
    NSDictionary *userInfo = notification.userInfo;
    AVAudioSessionInterruptionType type = [[userInfo valueForKey:AVAudioSessionInterruptionTypeKey] integerValue];
    if (type == AVAudioSessionInterruptionTypeBegan) {
        NSLog(@"來(lái)電鬧鐘暫停");
        [self.player pause];
    }
    if (type == AVAudioSessionInterruptionTypeEnded) {
        NSLog(@"結(jié)束繼續(xù)播放");
        [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()
        }

處理外設(shè)改變

- (void)audioSessionRouteChange:(NSNotification *)notify {
    NSDictionary *userInfo = notify.userInfo;
    NSInteger routeChangeReason = [[userInfo valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
    switch (routeChangeReason) {
        case AVAudioSessionRouteChangeReasonNewDeviceAvailable:
            NSLog(@"耳機(jī)插入");
            // 繼續(xù)播放音頻,什么也不用做
            break;
        case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:
            NSLog(@"耳機(jī)拔出");
            // 注意:拔出耳機(jī)時(shí)系統(tǒng)會(huì)自動(dòng)暫停你正在播放的音頻,因此只需要改變UI為暫停狀態(tài)即可
            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("繼續(xù)播放")
            break
            
        case .oldDeviceUnavailable:
            self.player.pause()
            break
        default:
        break
        }
    }

最后要記得remove掉注冊(cè)的通知哦

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

//swift
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容