AVAudioSession

转载自:https://www.jianshu.com/p/fb0e5fb71b3c

image.png

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同样可以监听外设音频状态,比如耳机拔入拔出。这里不做累述

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345