转载自:https://www.jianshu.com/p/fb0e5fb71b3c
AVAudioSession的官方解释:充当您的应用程序与操作系统之间以及中间的音频硬件之间的中介。您可以使用音频会话向操作系统传达应用音频的性质,而无需详细说明特定行为或与音频硬件的必要交互。此行为将对这些详细信息的管理委派给音频会话,从而确保操作系统可以最佳地管理用户的音频体验。
Category
类别
Category | 是否允许音频播放/录音 | 是否打断其他不支持混音APP | 是否会被静音键或锁屏键静音 |
---|---|---|---|
AVAudioSessionCategoryAmbient | 只支持播放 | 否 | 是 |
AVAudioSessionCategoryAudioProcessing | 不支持播放,不支持录制 | 是 | 否 |
AVAudioSessionCategoryMultiRoute | 支持播放,支持录制 | 是 | 否 |
AVAudioSessionCategoryPlayAndRecord | 支持播放,支持录制 | 默认YES,可以重写为NO | 否 |
AVAudioSessionCategoryPlayback | 只支持播放 | 默认YES,可以重写为NO | 否 |
AVAudioSessionCategoryRecord | 只支持录制 | 是 | 否(锁屏下仍可录制) |
AVAudioSessionCategorySoloAmbient | 只支持播放 | 是 | 是 |
AVAudioSessionCategoryAmbient
,只支持音频播放。这个 Category,音频会被静音键和锁屏键静音。并且不会打断其他应用的音频播放。AVAudioSessionCategorySoloAmbient
,这个是系统默认使用的 Category,只支持音频播放。音频会被静音键和锁屏键静音。和AVAudioSessionCategoryAmbient不同的是,这个会打断其他应用的音频播放AVAudioSessionCategoryPlayback
,只支持音频播放。你的音频不会被静音键和锁屏键静音。适用于音频是主要功能的APP,像网易云这些音乐app,锁屏后依然可以播放。
需要注意一下,选择支持在静音键切到静音状态以及锁屏键切到锁屏状态下仍然可以播放音频 Category 时,必须在应用中开启支持后台音频功能。
-
AVAudioSessionCategoryRecord
,只支持音频录制。不支持播放。 -
AVAudioSessionCategoryPlayAndRecord
,支持音频播放和录制。音频的输入和输出不需要同步进行,也可以同步进行。需要音频通话类应用,可以使用这个 Category。 -
AVAudioSessionCategoryAudioProcessing
,只支持本地音频编解码处理。不支持播放和录制。 -
AVAudioSessionCategoryMultiRoute
,支持音频播放和录制。允许多条音频流的同步输入和输出。(比如USB连接外部扬声器输出音频,蓝牙耳机同时播放另一路音频这种特殊需求)
您可以使用AVAudioSession对象配置应用的音频会话。 AVAudioSession是一个单例对象,用于设置音频会话类别和执行其他配置。您可以在应用的整个生命周期中与音频会话进行交互,但是在应用启动时执行此配置通常很有用,如以下示例所示。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]?) -> Bool {
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(AVAudioSessionCategoryPlayback)
} catch {
print("Setting category to AVAudioSessionCategoryPlayback failed.")
}
// Other project setup
return true
}
AVAudioSession 设置后整个APP都有效
- 音频会话的类别定义了应用程序打算如何使用音频。 通常,您在激活会话之前设置类别。 您也可以在会话处于活动状态时设置类别,但这会导致立即更改路由。
- (BOOL)setCategory:(AVAudioSessionCategory)category error:(NSError **)outError
AVAudioSessionCategory
取值类型
//播放录制的音乐或其他声音(对于成功使用您的应用至关重要的类别)。
AVAudioSessionCategoryPlayback
使用此类别时,您的应用程序音频会继续将“静音”开关设置为“无声”或屏幕锁定。 (此开关在iPhone上称为Ring / Silent开关。)要在您的应用转换为背景(例如,屏幕锁定)时继续播放音频,请将音频值添加到信息属性列表文件中的UIBackgroundModes键。
默认情况下,使用此类别表示您的应用的音频是不可混合的-激活会话将中断任何其他不可混合的音频会话。 要允许混合使用此类别,请使用AVAudioSessionCategoryOptionMixWithOthers选项。
- 激活或停用您的应用的音频会话。
如果另一个活动的音频会话的优先级高于您的优先级(例如,电话),并且两个音频会话都不允许混音,则尝试激活您的音频会话会失败。 停用具有正在运行的音频对象的音频会话将停止正在运行的音频对象,并停用该会话,并且将返回AVAudioSessionErrorCodeIsBusy错误。
使用“YES”激活您的应用的音频会话,或使用“NO”取消激活它。
- (BOOL)setActive:(BOOL)active error:(NSError * _Nullable *)outError;
AVAudioSession Mode
模式 | 兼容的 Category | 场景 |
---|---|---|
AVAudioSessionModeDefault | All | 默认模式 |
AVAudioSessionModeVoiceChat | AVAudioSessionCategoryPlayAndRecord | VoIP |
AVAudioSessionModeGameChat | AVAudioSessionCategoryPlayAndRecord | 游戏录制,GKVoiceChat自动设置 |
AVAudioSessionModeVideoRecording | AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryRecord | 录制视频 |
AVAudioSessionModeMoviePlayback | AVAudioSessionCategoryPlayback | 视频播放 |
AVAudioSessionModeMeasurement | AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryRecord AVAudioSessionCategoryPlayback | 最小系统 |
AVAudioSessionModeVideoChat | AVAudioSessionCategoryPlayAndRecord | 视频通话 |
AVAudioSessionModeDefault
,默认模式,与所有的 Category 兼容
AVAudioSessionModeVoiceChat
,适用于VoIP 类型的应用。只能是 AVAudioSessionCategoryPlayAndRecord Category下。在这个模式系统会自动配置AVAudioSessionCategoryOptionAllowBluetooth 这个选项。系统会自动选择最佳的内置麦克风组合支持语音聊天。
AVAudioSessionModeVideoChat
,用于视频聊天类型应用,只能是 AVAudioSessionCategoryPlayAndRecord Category下。适在这个模式系统会自动配置 AVAudioSessionCategoryOptionAllowBluetooth 和 AVAudioSessionCategoryOptionDefaultToSpeaker 选项。系统会自动选择最佳的内置麦克风组合支持视频聊天。
AVAudioSessionModeGameChat
,适用于游戏类应用。使用 GKVoiceChat 对象的应用会自动设置这个模式和 AVAudioSessionCategoryPlayAndRecord Category。实际参数和AVAudioSessionModeVideoChat一致
AVAudioSessionModeVideoRecording
,适用于使用摄像头采集视频的应用。只能是 AVAudioSessionCategoryPlayAndRecord 和 AVAudioSessionCategoryRecord 这两个 Category下。这个模式搭配 AVCaptureSession API 结合来用可以更好地控制音视频的输入输出路径。(例如,设置 automaticallyConfiguresApplicationAudioSession 属性,系统会自动选择最佳输出路径。
AVAudioSessionModeMeasurement
,最小化系统。只用于 AVAudioSessionCategoryPlayAndRecord、AVAudioSessionCategoryRecord、AVAudioSessionCategoryPlayback 这几种 Category。
AVAudioSessionModeMoviePlayback
,适用于播放视频的应用。只用于 AVAudioSessionCategoryPlayback 这个Category。
AVAudioSession Options
Option | Option功能说明 | 兼容的 Category |
---|---|---|
AVAudioSessionCategoryOptionMixWithOthers | 支持和其他APP音频 mix | AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryPlayback AVAudioSessionCategoryMultiRoute |
AVAudioSessionCategoryOptionDuckOthers | 系统智能调低其他APP音频音量 | AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryPlayback AVAudioSessionCategoryMultiRoute |
AVAudioSessionCategoryOptionAllowBluetooth | 支持蓝牙音频输入 | AVAudioSessionCategoryRecord AVAudioSessionCategoryPlayAndRecord |
AVAudioSessionCategoryOptionDefaultToSpeaker | 设置默认输出音频到扬声器 | AVAudioSessionCategoryPlayAndRecord |
调优我们的Category
通过Category和合适的Mode和Options的搭配我们可以调优出我们的效果,下面举两个应用场景:
用过高德地图的都知道,在后台播放QQ音乐的时候,如果导航语音出来,QQ音乐不会停止,而是被智能压低和混音,等导航语音播报完后,QQ音乐正常播放,这里我们需要后台播放音乐,所以Category使用AVAudioSessionCategoryPlayback,需要混音和智能压低其他APP音量,所以Options选用 AVAudioSessionCategoryOptionMixWithOthers和AVAudioSessionCategoryOptionDuckOthers
音频中断处理
其他APP或者电话会中断我们的APP音频,所以相应的我们要做出处理。
我们可以通过监听AVAudioSessionInterruptionNotification这个key获取音频中断事件
回调回来Userinfo有键值
AVAudioSessionInterruptionTypeKey:
取值AVAudioSessionInterruptionTypeBegan表示中断开始
取值AVAudioSessionInterruptionTypeEnded表示中断结束
中断开始:我们需要做的是保存好播放状态,上下文,更新用户界面等
中断结束:我们要做的是恢复好状态和上下文,更新用户界面,根据需求准备好之后选择是否激活我们session。
选择不同的音频播放技术,处理中断方式也有差别,具体如下:
System Sound Services:使用 System Sound Services 播发音频,系统会自动处理,不受APP控制,当中断发生时,音频播放会静音,当中断结束后,音频播放会恢复。
AV Foundation framework:AVAudioPlayer 类和 AVAudioRecorder 类提供了中断开始和结束的 Delegate 回调方法来处理中断。中断发生,系统会自动停止播放,需要做的是记录播放时间等状态,更新用户界面,等中断结束后,再次调用播放方法,系统会自动激活session。
Audio Queue Services, I/O audio unit:使用aduio unit这些技术需要处理中断,需要做的是记录播放或者录制的位置,中断结束后自己恢复audio session。
OpenAL:使用 OpenAL 播放时,同样需要自己监听中断。管理 OpenAL上下文,用户中断结束后恢复audio session。
需要注意的是:1. 有中断开始事件,不一定对应有中断结束事件,所以需要在用户进入前台,点击UI操作的时候,需要保存好播放状态和对Audio Session管理,以便不影响APP的音频功能。2.音频资源竞争上,一定是电话优先。3. AVAudioSession同样可以监听外设音频状态,比如耳机拔入拔出。这里不做累述