iOS音频播放(2):AVAudioSession

前面一篇中的七个步骤之前我们还得知道AudioSession个问题。

本片就先讲AudioSession的使用和一些需要注意的地方。

1、AudioSession概述

AudioSession主要作用有一下几点:
  • 设置自己的APP是否和其他APP音频同时存在,还是中断其他APP声音
  • 在手机调到静音模式下,自己的APP音频是否可以播放出声音
  • 电话或者其他APP中断自己APP的音频的事件处理
  • 指定音频输入和输出的设备(比如是听筒输出声音,还是扬声器输出声音)
  • 是否支持录音,录音同时是否支持音频播放
ASPG_intro_2x.png

AudioSession相关的类有两个

AudioToolbox中的AudioSession。
AVFoundation中的AVAudioSession。

AudioSession在SDK7中已经被标注为depracated了,而AVAudioSession这个类虽然iOS 3开始就已经存在了,但其中很多方法和变量都是在iOS 6以后甚至是iOS 7才有的。所以各位可以依照以下标准选择:

  • 如果最低版本支持iOS 5,可以使用AudioSession,也可以使用AVAudioSession;
  • 如果最低版本支持iOS 6及以上,请使用AVAudioSession

现在应该很少有需要支持iOS 5的了吧,我就以AVAudioSession为例吧.

//    AVAudioSession是一个到单例
    AVAudioSession *audiosession = [AVAudioSession sharedInstance];
//    AVAudioSessionCategorySoloAmbient系统默认的
    [audiosession setCategory:AVAudioSessionCategorySoloAmbient error:nil];
//    激活AVAudioSession
    [audiosession setActive:YES error:nil];
Category目前有七种,其中对应了是否支持一下四种能力:
  • Interrupts non-mixable apps audio:是否打断不支持混音播放的APP
  • Silenced by the Silent switch:是否会响应手机静音键开关
  • Supports audio input:是否支持音频录制
  • Supports audio output:是否支持音频播放
Category 是否允许音频播放/录音 是否打断其他不支持混音APP 是否会被静音键或锁屏键静音
AVAudioSessionCategoryAmbient 只支持播放
AVAudioSessionCategoryAudioProcessing 不支持播放,不支持录制
AVAudioSessionCategoryMultiRoute 支持播放,支持录制
AVAudioSessionCategoryPlayAndRecord 支持播放,支持录制 默认YES,可以重写为NO
AVAudioSessionCategoryPlayback 只支持播放 默认YES,可以重写为NO
AVAudioSessionCategoryRecord 只支持录制 否(锁屏下仍可录制)
AVAudioSessionCategorySoloAmbient 只支持播放

我们也可以通过AVAudioSession的属性来读取当前设备支持的Category
@property(readonly) NSArray<NSString *> *availableCategories;
这样可以保证设备的兼容性
设置Category的代码示例如下:

NSError *setCategoryError = nil;
BOOL isSuccess = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:&setCategoryError];
if (!success) { 
    //这里可以读取setCategoryError.localizedDescription查看错误原因
}

AVAudioSession Mode&&Options

刚刚介绍的Category定义了七种主场景,实际开发需求中有时候需要对Category进行微调整,我们发现这个接口还有两个参数Mode和Options。

/* set session category and mode with options */
- (BOOL)setCategory:(NSString *)category mode:(NSString *)mode options:(AVAudioSessionCategoryOptions)options error:(NSError **)outError API_AVAILABLE(ios(10.0), watchos(3.0), tvos(10.0));

//    也可以通过属性来读取
@property(readonly) NSArray<NSString *> *availableModes;
有七种mode来定制我们的Category行为:

1、 AVAudioSessionModeDefault:默认模式,与所有的 Category 兼容。
2、 AVAudioSessionModeVoiceChat:只有与AVAudioSessionCategoryPlayAndRecord有效。适用于IP语音。(VoIP)应用程序。减少允许的音频路由的数量。这适用于VoIP应用程序,并可采用适当的系统提供。信号处理。是否设置了AVAudioSessionCategoryOptionAllowBluetooth?
3、 AVAudioSessionModeGameChat:由Game Kit代表使用GKVoiceChat对象的应用程序设置;有效的只有AVAudioSessionCategoryPlayAndRecord类别。不要直接设置此模式。如果你需要类似的行为并且不使用。
一个GKVoiceChat对象,使用AVAudioSessionModeVoiceChat代替。
4、 AVAudioSessionModeVideoRecording:只对AVAudioSessionCategoryPlayAndRecord/AVAudioSessionCategoryRecord有效。修改音频路由选项,并可能参与适当的系统提供的信号处理。
5、AVAudioSessionModeMeasurement:适用于希望最小化系统提供的信号效果的应用程序。处理输入和/或输出音频信号。
6、AVAudioSessionModeMoviePlayback:对电影播放场景进行适当的输出信号处理。目前只在播放时使用内置扬声器。
7、AVAudioSessionModeVideoChat:用于视频聊天类型应用,只能是 AVAudioSessionCategoryPlayAndRecord Category下。适在这个模式系统会自动配置 AVAudioSessionCategoryOptionAllowBluetooth 和 AVAudioSessionCategoryOptionDefaultToSpeaker 选项。系统会自动选择最佳的内置麦克风组合支持视频聊天。

AVAudioSession Options

1、AVAudioSessionCategoryOptionMixWithOthers:支持和其他APP音频 mix
2、AVAudioSessionCategoryOptionDuckOthers:系统智能调低其他APP音频音量
3、AVAudioSessionCategoryOptionAllowBluetooth:支持蓝牙音频输入
4、AVAudioSessionCategoryOptionDefaultToSpeaker:设置默认输出音频到扬声器

通过Category和合适的Mode和Options的搭配我们可以调优出我们的效果,下面举两个应用场景:
用过高德地图的都知道,在后台播放QQ音乐的时候,如果导航语音出来,QQ音乐不会停止,而是被智能压低和混音,等导航语音播报完后,QQ音乐正常播放,这里我们需要后台播放音乐,所以Category使用AVAudioSessionCategoryPlayback,需要混音和智能压低其他APP音量,所以Options选用 AVAudioSessionCategoryOptionMixWithOthers和AVAudioSessionCategoryOptionDuckOthers

BOOL isSuccess = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers | AVAudioSessionCategoryOptionDuckOthers error:&setCategoryError];

//又或者我希望AVAudioSessionCategoryPlayAndRecord这个Category默认的音频由扬声器播放,那么可以调用这个接口去调整Category
- (BOOL)setCategory:(NSString *)category withOptions:(AVAudioSessionCategoryOptions)options error:(NSError **)outError
音频中断处理

其他APP或者电话会中断我们的APP音频,所以相应的我们要做出处理。
我们可以通过监听AVAudioSessionInterruptionNotification和AVAudioSessionSilenceSecondaryAudioHintNotification两个key获取音频中断事件

AVAudioSessionInterruptionNotification监听电话、闹铃等一般性的中断
回调回来Userinfo有两个键值

  • AVAudioSessionInterruptionTypeKey:
    取值AVAudioSessionInterruptionTypeBegan表示中断开始
    取值AVAudioSessionInterruptionTypeEnded表示中断结束

  • AVAudioSessionInterruptionOptionKey:
    取值AVAudioSessionInterruptionOptionShouldResume表示可以恢复播放
    AVAudioSessionSilenceSecondaryAudioHintNotification监听其他APP占据AudioSession,回调回来Userinfo有一个键值

  • AVAudioSessionSilenceSecondaryAudioHintTypeKey:
    取值AVAudioSessionSilenceSecondaryAudioHintTypeBegin表示中断开始
    取值AVAudioSessionSilenceSecondaryAudioHintTypeEnd表示中断结束

中断开始:我们需要做的是保存好播放状态,上下文,更新用户界面等
中断结束:我们要做的是恢复好状态和上下文,更新用户界面,根据需求准备好之后选择是否激活我们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.音频资源竞争上,一定是电话优先。

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

推荐阅读更多精彩内容