0%

音频打断处理

音频打断处理

音频打断通知:

AVAudioSessionInterruptionNotification

音频会话被系统打断时会收到该通知.打断开始会收到该通知,打断结束也会收到该通知.可以通过userInfo里的AVAudioSessionInterruptionTypeKeykey查看打断的类型:

1
2
3
4
5
6
7
8
9
typedef NS_ENUM(NSUInteger, AVAudioSessionInterruptionType)
{
AVAudioSessionInterruptionTypeBegan = 1, /* the system has interrupted your audio session */
AVAudioSessionInterruptionTypeEnded = 0, /* the interruption has ended */
};

/* keys for AVAudioSessionInterruptionNotification */
/* Value is an NSNumber representing an AVAudioSessionInterruptionType */
AVF_EXPORT NSString *const AVAudioSessionInterruptionTypeKey API_AVAILABLE(ios(6.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos);

如果是打断结束类型,则userInfo里会有一个AVAudioSessionInterruptionOptionskey,它的值是AVAudioSessionInterruptionOptions枚举类型.用于表示打断结束后是否应该继续播放.

1
2
3
4
5
/* For use with AVAudioSessionInterruptionNotification */
typedef NS_OPTIONS(NSUInteger, AVAudioSessionInterruptionOptions)
{
AVAudioSessionInterruptionOptionShouldResume = 1
};

如果打断是因为应用被挂起,则userInfo里会有一个AVAudioSessionInterruptionWasSuspendedKeykey,并且值是true.(这个key有点奇葩)

使用如下:

注册AVAudioSessionInterruptionNotification通知:

1
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerAudioBeInterrupted:) name:AVAudioSessionInterruptionNotification object:nil];

处理通知:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- (void)playerAudioBeInterrupted:(NSNotification *)notification
{
NSDictionary *userInfo = notification.userInfo;
NSLog(@"音频打断userInfo:%@", userInfo);
AVAudioSessionInterruptionType interruptionType = [userInfo[AVAudioSessionInterruptionTypeKey] integerValue];
if (interruptionType == AVAudioSessionInterruptionTypeBegan) {//打断开始
//这个时候要暂停播放器
...
} else if (interruptionType == AVAudioSessionInterruptionTypeEnded) {//打断结束
AVAudioSessionInterruptionOptions options = [userInfo[AVAudioSessionInterruptionOptionKey] integerValue];
if (options == AVAudioSessionInterruptionOptionShouldResume) { //可以继续播放
//继续播放
...
} else { //不处理

}
} else {
NSLog(@"未知");
}
}

PS:在开发的时候遇到一个坑:
在app内听音乐,点暂停,然后进入后台一段时间,再从后台进入前台时,音乐居然自动播放了.
最后找到原因:上述操作后,在进入前台时会收到AVAudioSessionInterruptionNotification通知.之前代码在打断结束的判断中没有继续判断是否应该恢复播放,而直接调用了play方法,导致上述bug.

打印日志如下:

1
2
3
4
5
6
7
8
9
10
11
19:04:56.847796 +0800	EmotionCounsel	app did resume
19:04:56.850945 +0800 EmotionCounsel AVAudioSession.mm:2136:-[AVAudioSession privateInterruptionWithInfo:]: Posting AVAudioSessionInterruptionNotification (Begin Interruption). Was suspended:1
19:04:56.851301 +0800 EmotionCounsel 音频打断userInfo:{
AVAudioSessionInterruptionTypeKey = 1;
AVAudioSessionInterruptionWasSuspendedKey = 1;
}
19:04:56.851538 +0800 EmotionCounsel AVAudioSession.mm:2156:-[AVAudioSession privateInterruptionWithInfo:]: Posting AVAudioSessionInterruptionNotification (End Interruption). Resumable:0
19:04:56.851616 +0800 EmotionCounsel 音频打断userInfo:{
AVAudioSessionInterruptionOptionKey = 0;
AVAudioSessionInterruptionTypeKey = 0;
}
觉得文章有帮助可以打赏一下哦!