我们在开发中使用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)
}