AudioSession 简介
AudioSession 这个玩意的主要功能包括以下几点(图片来自官方文档):
1、确定你的 APP 如何使用音频,是播放还是录音
2、为你的 APP选择合适的输入输出设备(如输入用麦克风、输出用耳机、手机功放或者 AirPlay)
3、协调你的 APP 的音频播放和系统以及其他 APP 的行为(如电话打断,结束电话时恢复,按下静音按钮时是否歌曲也要静音等)
与 AudioSession 相关的类有2个
1、AudioToolBox 中的 AudioSession
2、AVFoundation 中的 AVAudioSession
AudioSession在SDK7中已被标注为depracated,在此由于最高版本已经到 iOS11, 所以对 AVAudioSession 进行说明。
AVAudioSession 为单例,其初始化方法如下
// 初始化 session
+ (AVAudioSession *)sharedInstance;
激活AVAudioSession
激活 AVAudioSession的方法有两个 ,如下:第2个方法所用的枚举在这里会进行相应的讲解
- (BOOL)setActive:(BOOL)active error:(NSError **)outError;
/* AVAudioSessionSetActiveOptions 这个枚举只有一个值:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation 关于这个枚举做以下2点说明
* 作用是通知中断的应用程序中断已经结束,可以恢复播放,只对某个会话停了的 APP 有效。
* 因为AVAudioSession会影响其他 APP 的表现,当自己 APP 的 session 被激活,其他 APP 的 session 机会被解除激活,如何让自己的 APP 解除激活后恢复其他 APP 的表现 就需要用到这个枚举
*/
- (BOOL)setActive:(BOOL)active withOptions:(AVAudioSessionSetActiveOptions)options error:(NSError **)outError
七大Category
AVAudioSession 主要能控制 APP 的哪些表现以及如何控制呢?首先 AVAudioSeeson 将使用音频的场景分成7大类,通过设置 Session 的不同类别进行控制,设置类别的方法有如下4个
/** 7大 Category *
* AVAudioSessionCategoryAmbient : 设置这种category,声音可作为背景音,如在打游戏的时候想听 QQ 音乐,那么把游戏的背景音就设置为这种category。使用这个 category 会随着静音键和屏幕的关闭而静音。应用于非语音为主的应用
* AVAudioSessionCategorySoloAmbient : 类似于AVAudioSessionCategoryAmbient。只用于播放,它会终止其他 APP 播放音频
* AVAudioSessionCategoryPlayback : 适用于 APP 本身就是一个音频播放器,用这个 category,不会随着静音键和屏幕的关闭而静音
* AVAudioSessionCategoryRecord : 用于需要录音的应用,设置了该 category,除了来电铃声、闹钟、日历提醒之外的其他声音都不会被播放,该 category 只提供录音功能。
* AVAudioSessionCategoryPlayAndRecord : 用于既需要播放有需要录音的应用,比如打电话的时候需要录音,如果应用需要用到 iPhone 上的听筒,那么该 Category 是你唯一的选择,在没有外接设备的情况下,该 category 下的声音默认出口为听筒
* AVAudioSessionCategoryAudioProcessing : 用于音频格式处理,一般和 AudioUnit 配合使用
* AVAudioSessionCategoryMultiRoute : 这个类别为应用程序提供了同时使用USB输出和耳机输出的能力,用于单独的、不同的音频数据流.使用此 category 需要更详细的了解音频路由的功能,并与之交互。可用于输入、输出或两者兼用。注意,不是所有的输出类型和
输出组合适合于多路由。输入限制在最后一个输入端口。合格的输入如下:AVAudioSessionPortUSBAudio, AVAudioSessionPortHeadsetMic, AVAudioSessionPortBuiltInMic.合格的输出如下:AVAudioSessionPortUSBAudio, AVAudioSessionPortLineOut, AVAudioSessionPortHeadphones, AVAudioSessionPortHDMI, AVAudioSessionPortBuiltInSpeaker(只允许在没有其他合适的输出连接时使用)
*/
- (BOOL)setCategory:(NSString *)category error:(NSError **)outError;
七大 Category可以认为设定了7种场景,而这七个 Category肯定不能满足开发者的所有需求,因此又提供了7个 Options 进行微调。
/** AVAudioSessionCategoryOptions *
* AVAudioSessionCategoryOptionMixWithOthers : 试用 category AVAudioSessionCategoryPlayAndRecord、AVAudioSessionCategoryMultiRoute、AVAudioSessionCategoryPlayback。 设置背景音
* AVAudioSessionCategoryOptionDuckOthers : 试用 category AVAudioSessionCategoryAmbient AVAudioSessionCategoryPlayAndRecord、AVAudioSessionCategoryMultiRoute、AVAudioSessionCategoryPlayback。通过设置这个选项对其他 APP 的声音进行压制
* AVAudioSessionCategoryOptionAllowBluetooth : 试用 category AVAudioSessionCategoryPlayAndRecord、 AVAudioSessionCategoryRecord。 支持蓝牙耳机通话或者录音则需要设置这个选项
* AVAudioSessionCategoryOptionDefaultToSpeaker : 试用 category AVAudioSessionCategoryPlayAndRecord。如果在 VoIP 模式下,默认打开免提功能,需要设置这个选项
* AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers : 试用 category AVAudioSessionCategoryPlayAndRecord、AVAudioSessionCategoryMultiRoute、AVAudioSessionCategoryPlayback。适用于 APP偶尔进行音频能播放
* AVAudioSessionCategoryOptionAllowBluetoothA2DP : 试用 category AVAudioSessionCategoryPlayAndRecord。支持立体声蓝牙
* AVAudioSessionCategoryOptionAllowAirPlay : 试用 category AVAudioSessionCategoryPlayAndRecord。支持AirPlay
*/
- (BOOL)setCategory:(NSString *)category withOptions:(AVAudioSessionCategoryOptions)options error:(NSError **)outError
八大模式,通过上面的七大 Category,我们基本覆盖了常用的主场景,在每个主场景中我们可以通过 Opition 进行微调,为此 CoreAudio 提供了八大比较常见微调后的子场景。叫做各个类别的模式。
/** mode *
* AVAudioSessionModeDefault:默认模式,适用于所有场景
* AVAudioSessionModeVoiceChat: 只有与AVAudioSessionCategoryPlayAndRecord有效。适用于IP网络电话的应用。减少允许的音频路由的数量,使之只适用于VoIP应用程序,并可能参与适当的系统提供的信号处理。有设置 Opitions 为 AVAudioSessionCategoryOptionAllowBluetooth 的副作用
* AVAudioSessionModeGameChat : 适用于游戏App的采集和播放,比如“GKVoiceChat”对象,一般不需要手动设置
* AVAudioSessionModeVideoChat : 主要用于视频通话,比如QQ视频、FaceTime。时系统也会选择最佳的输入设备,比如插上耳机就使用耳机上的麦克风进行采集并且会设置类别的选项为"AVAudioSessionCategoryOptionAllowBluetooth" 和 "AVAudioSessionCategoryOptionDefaultToSpeaker"
* AVAudioSessionModeVideoRecording : 仅对AVAudioSessionCategoryPlayAndRecord或AVAudioSessionCategoryRecord有效。修改音频路由选项并可能进行适当的系统提供的信号处理。
* AVAudioSessionModeMeasurement : 适用于希望将系统提供的信号处理对输入和/或输出音频信号的影响降到最低的应用程序。
* AVAudioSessionModeMoviePlayback : 为视频回放场景进行适当的信号处理。目前只适用于内置扬声器的播放
* AVAudioSessionModeSpokenAudio : 当想要在另一个应用播放短语音频时暂停当前音频时,用于持续说话音频的模式。
*/
- (BOOL)setMode:(NSString *)mode error:(NSError **)outError
系统中断响应
AVAudioSession 提供了多种 Notifications 来通知当前 APP 中断,其中将电话、闹铃等都归结为一般性的中断用AVAudioSessionInterruptionNotification来通知,其回调的 userInfo 主要有两个键,如下:
1、AVAudioSessionInterruptionTypeKey 有两个值
(1)取值为AVAudioSessionInterruptionTypeBegan表示中断开始,我们应该暂停播放和采集。
(2)表示中断结束,我们可以继续播放和采集。
2、AVAudioSessionInterruptionOptionShouldResume 表示此时也应该恢复继续播放和采集。
而其他 APP 占据AVAudioSession的时候AVAudioSessionSilenceSecondaryAudioHintNotification会发来通知,其回调回来的 userInfo可能包含的值为
1、AVAudioSessionSilenceSecondaryAudioHintTypeBegin:其他 APP 开始占据 Session
2、AVAudioSessionSilenceSecondaryAudioHintTypeEnd:其他 App 开始释放 Session
外设改变
用户也可以对我们的 APP 产生影响,会通过AVAudioSessionRouteChangeNotification回调回来 userInfo,其键为
1、AVAudioSessionRouteChangeReasonKey,表示改变原因值为
(1)AVAudioSessionRouteChangeReasonUnknown:未知原因
(2)AVAudioSessionRouteChangeReasonNewDeviceAvailable :有新设备可用
(3)AVAudioSessionRouteChangeReasonOldDeviceUnavailable:旧设备不可用
(4)AVAudioSessionRouteChangeReasonCategoryChange:Category 改变了
(5)AVAudioSessionRouteChangeReasonOverride:APP 重置了输出设置
(6)AVAudioSessionRouteChangeReasonWakeFromSleep:从睡眠状态呼醒
(7)AVAudioSessionRouteChangeReasonNoSuitableRouteForCategory:当前 Category 下没有合适的设备
(8)可以AVAudioSessionRouteChangeReasonRouteConfigurationChange:router 的配置改变了
2、AVAudioSessionSilenceSecondaryAudioHintTypeKey:和上面的中断一意
总结:AVAudioSession构建了一个音频使用生命周期的上下文。当前状态是否可以录音、对其他App有怎样的影响、是否响应系统的静音键、如何感知来电话了等都可以通过它来实现。尤为重要的是AVAudioSession不仅可以和AVFoundation中的AVAudioPlyaer/AVAudioRecorder配合,其他录音/播放工具比如AudioUnit、AudioQueueService也都需要他进行录音、静音等上下文配合。