AVAudioSession介绍
音频输出作为硬件资源,对于ios系统来说是唯一的;AVAudioSession可以协调和各个App之间对这个稀缺资源的硬件持有关系,
1、实现对App当前上下文音频资源的控制;比如:插拔耳机、接电话、是否和其他音频数据混音等。
- 是进行录音还是播放?
- 当系统静音键按下时该如何表现?
- 是从扬声器还是从听筒里面播放声音?
- 插拔耳机后如何表现?
- 来电话/闹钟响了后如何表现?
- 其他音频App启动后如何表现?
2、Session的默认行为:
- 可以进行播放,但是不能进行录制
- 当用户将手机上的静音拨片拨到“静音”状态时,此时如果正在播放音频,那么播放内容会被静音
- 当用户按了手机的锁屏键或者手机自动锁屏了,此时如果正在播放音频,那么播放会静音并被暂停
- 如果你的App在开始播放的时候,此时QQ音乐等其他App正在播放,那么其他播放器会被静音并暂停
- 默认的行为相当于设置了Category为“AVAudioSessionCategorySoloAmbient”
AVAudioSession基本设置
//音频回话配置
AVAudioSession * session = [AVAudioSession sharedInstance];
NSError *error;
//选择音频会话类型
//只配置类别
if (![session setCategory:AVAudioSessionCategoryPlayback error:&error]) {
NSLog(@"error:%@",[error localizedDescription]);
}
//配置类别并配置相应的场景
if (![session setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&error]) {
NSLog(@"error:%@",[error localizedDescription]);
}
//配置类别配置场景并配置使用模式
if (![session setCategory:AVAudioSessionCategoryPlayback mode:AVAudioSessionModeDefault options:AVAudioSessionCategoryOptionMixWithOthers error:&error]) {
NSLog(@"error:%@",[error localizedDescription]);
}
//开启音频会话 -- 其他app就会被接触激活
if (![session setActive:YES error:&error]) {
NSLog(@"error:%@",[error localizedDescription]);
}
//开启音频会话 -- Session解除激活后恢复其他App Session的激活状态
if (![session setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&error]) {
NSLog(@"error:%@",[error localizedDescription]);
}
AVAudioSessionCategory 会话类别选择
AVAudioSessionCategoryAmbient: 当前App的播放声音可以和其他app播放的声音共存,当锁屏或按静音时停止
AVAudioSessionCategorySoloAmbient: 只能播放当前App的声音,其他app的声音会停止,当锁屏或按静音时停止
AVAudioSessionCategoryPlayback: 只能播放当前App的声音,其他app的声音会停止,当锁屏或按静音时不会停止
AVAudioSessionCategoryRecord: 只能用于录音,其他app的声音会停止,当锁屏或按静音时不会停止
AVAudioSessionCategoryPlayAndRecord: 在录音的同时播放其他声音,当锁屏或按静音时不会停止
AVAudioSessionCategoryAudioProcessing: 使用硬件解码器处理音频,该音频会话使用期间,不能播放或录音
AVAudioSessionCategoryMultiRoute: 多种音频输入输出,例如可以耳机、USB设备同时播放等
@property(readonly) NSArray<NSString *> *availableCategories; //查看当前设备支持哪些类别
@property(readonly) NSString *category; [AVAudioSession sharedInstance].category //获取当前的类别
AVAudioSessionCategoryOptions 回话类别的常用场景
AVAudioSessionCategoryOptionMixWithOthers:
在AVAudioSessionCategoryPlayAndRecord | AVAudioSessionCategoryPlayback | AVAudioSessionCategoryMultiRoute 下使用
AVAudioSessionCategoryOptionDuckOthers
在AVAudioSessionCategoryAmbient | AVAudioSessionCategoryPlayAndRecord | AVAudioSessionCategoryPlayback | AVAudioSessionCategoryMultiRoute 下使用
AVAudioSessionCategoryOptionAllowBluetooth
在AVAudioSessionCategoryRecord | AVAudioSessionCategoryPlayAndRecord 下使用
AVAudioSessionCategoryOptionDefaultToSpeaker
在AVAudioSessionCategoryPlayAndRecord 下使用
AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers
在AVAudioSessionCategoryPlayAndRecord | AVAudioSessionCategoryPlayback | AVAudioSessionCategoryMultiRoute 下使用
AVAudioSessionCategoryOptionAllowBluetoothA2DP
在AVAudioSessionCategoryPlayAndRecord 下使用
AVAudioSessionCategoryOptionAllowAirPlay
在AVAudioSessionCategoryPlayAndRecord 下使用
AVAudioSessionMode 会话模式
AVAudioSessionModeDefault
//所有类别 默认的模式
AVAudioSessionModeVoiceChat
//AVAudioSessionCategoryPlayAndRecord 主要用于VoIP场景 此时系统会选择最佳的输入设备,比如插上耳机就使用耳机上的麦克风进行采集。
AVAudioSessionModeGameChat
//AVAudioSessionCategoryPlayAndRecord 适用于游戏App的采集和播放
AVAudioSessionModeVideoRecording //AVAudioSessionCategoryPlayAndRecord | AVAudioSessionCategoryRecord 录制视频
//AVAudioSessionCategoryPlayAndRecord | AVAudioSessionCategoryRecord | AVAudioSessionCategoryPlayback 最小系统
AVAudioSessionModeMeasurement
AVAudioSessionModeMoviePlayback //AVAudioSessionCategoryPlayback 视频播放
AVAudioSessionModeVideoChat //AVAudioSessionCategoryPlayAndRecord 视频通话
AVAudioSessionModeSpokenAudio // >=iOS9.0 如果其他应用(如导航应用程序)播放语音音频提示时,适用于希望暂停(通过音频会话中断)而不是躲避。使用此应用程序的示例是播客播放器和音频书
@property(readonly) NSArray<NSString *> *availableModes; 每个类别下适用的模式
系统中断响应
应用程序在播放的时候,难免会被打断!比如突然来电话了、闹钟响了或者你在后台放歌但是用户启动其他App用上面的方法影响的时候,我们需要先暂停,待恢复的时候再继续。那我们的App要如何感知到这个终端以及何时恢复呢?AVAudioSession提供了多种Notifications来进行此类状况的通知。
一、其中将来电话、闹铃响等都归结为一般性的中断,用AVAudioSessionInterruptionNotification来通知。其回调回来的userInfo主要包含两个键:
-
AVAudioSessionInterruptionTypeKey:
1、取值为AVAudioSessionInterruptionTypeBegan表示中断开始,我们应该暂停播放和采集
2、取值为AVAudioSessionInterruptionTypeEnded表示中断结束,我们可以继续播放和采集 -
AVAudioSessionInterruptionOptionKey
当前只有一种值AVAudioSessionInterruptionOptionShouldResume表示此时也应该恢复继续播放和采集。
二、线路改变的处理:耳机的插入/拔出、断开麦克风等,会发生线路的变化
AVAudioSessionRouteChangeNotification 来通知,其回调回来的userInfo主要包含两个键:
- AVAudioSessionRouteChangeReasonKey 通过返回值可以推断出不同的事件
AVAudioSessionRouteChangeReasonUnknown 未知原因
AVAudioSessionRouteChangeReasonNewDeviceAvailable 有新设备可用
AVAudioSessionRouteChangeReasonOldDeviceUnavailable 老设备不可用
AVAudioSessionRouteChangeReasonCategoryChange 类别改变
AVAudioSessionRouteChangeReasonOverride App重置了输出设置
AVAudioSessionRouteChangeReasonWakeFromSleep 从睡眠状态呼醒
AVAudioSessionRouteChangeReasonNoSuitableRouteForCategory 当前Category下没有合适的设备
AVAudioSessionRouteChangeReasonRouteConfigurationChange Rotuer的配置改变了
- AVAudioSessionRouteChangePreviousRouteKey 获得上一线路的描述信息,注意线路的描述信息整合在一个输入NSArray和一个输出NSArray中,数组中的元素都是 AVAudioSessionPortDescription 对象.我们需要从线路描述中找到第一个输出接口并判断其是否为耳机接口,如果为耳机,则停止播放.
- 只有这两个结合起来才可断定为耳机断开
三、而将其他App占据AudioSession的时候用AVAudioSessionSilenceSecondaryAudioHintNotification来进行通知。其回调回来的userInfo键为:
- AVAudioSessionSilenceSecondaryAudioHintTypeKey
1、AVAudioSessionSilenceSecondaryAudioHintTypeBegin: 表示其他App开始占据Session
2、AVAudioSessionSilenceSecondaryAudioHintTypeEnd: 表示其他App开始释放Session
网友评论