audiosession负责调节你的app和ios系统里的音频行为.一旦加载了audiosession你可以获得一个audiosession的单例.你可以配置这个audiosession来控制你的app的音频行为.例如:
- 当你的app播放声音的时候,你是希望其他正在播放声音的app静音还是混合两个app的声音?
- 你的app如何回应突发的打断,例如这时候闹铃突然响了?
- 你的app又该如何回应耳机口的拔插呢?
AuioSession的配置会影响你的app在运行中所有的音频活动,除了利用System Sounds Services API控制的音频.
你还可以利用AudioSession来检测你所用硬件的参数,例如声道和采样率.
你还可以随时激活或者停止你的audioSession,当你的app播放声音或者正在录音的时候,你必须确保AudioSession处于激活状态.
系统也有权利随时中断你的audioSession,例如,当你来电话的时候.当然,AudioSession提供了api来让你的app从这种中断中恢复.
AudioSession的默认行为
AudioSession有一些默认的行为和规则.特别是以下几点.
- 当app正在播放声音时,是不能录音的.
- 当用户把静音键拨到静音的位置时,你的音频将会静音
- 当用户锁定屏幕或者手机自动进入锁屏模式的时候你的音频将会静音
- 当你的音频开始的时候,设备的其他正在播放的音频将会静音
以上所有的行为都是由一个默认的Audio Session类别控制的,AudioSessionCategorySoloAmbient.
当你播放或者录制音频的时候你的AudioSession就会自动启动.然而,依赖这些默认的配置可能会产生很多问题.比如,当你的手机接到电话,那么你的音频有可能不会播放,因为这决定于你使用哪种方式播放音频.
你当然可以从默认的AudioSession配置中获得很好的效果.但是,需要记住的是,对于一个上架的app来说.只有两种情形适用于使用默认的配置.
- 你的app只使用System Sound Services 或者UIKIt中的 playInputClick方法来播放音频.
- 你的app完全不使用任何音频
其他任何环境,都不要使用默认的AudioSession配置.
为什么一个默认的AudioSession配置通常并不是你想要的
如果你不显示的初始化,配置你的AudioSession,那么你就不能正确的处理系统的中断或者硬件路径的更改(例如耳机和功放的切换).而且,你的app对于系统决定不同app之间同时播放音频这种情况也毫无控制力.
以下是几种使用默认AudioSession配置可能导致的问题,以及你需要怎么做才能避免.
- 场景1.你写了一个语音图书的app,当用户正在听一个故事的时候,手机的自动锁屏时间到了.用户的屏幕锁住了,那么你的audio也自动静音了.
为了确保音频会在视频锁屏时继续播放,你需要配置你的AudioSession让他支持继续播放,在UIBackgroundModes中开启audio flag.
-
场景2.你写了一个第一人称射击游戏,游戏的音效是基于OpenAL的.并且你为玩家提供了一个功能,这个功能就是玩家可以关闭游戏提供的默认音效并且选择一首自己手机里的歌曲作为替代.然而,当玩家射击了敌军的一艘飞船时,音乐停止了.
为了确保音乐不会停止,你需要配置你的AudioSession使他允许混音,使用AVAudioSessionCategoryAmbient这个类别,或者修改AVAudioSessionCategoryPlayback这个类别使他支持混音. -
场景3.你使用Audio Queue Services写了一个流媒体播放app,当用户正在使用app时,一个电话来了,铃声打断了你的app.当用户选择忽略这个电话并且关掉铃声.当用户 重新点击Play按钮继续收听音乐,这时,什么都没发生,音乐并没有继续播放.用户不得不从后台关掉你的ap并且重新启动它.(我如果碰到这种app肯定 直接删掉了.)
为了解决这种中断audio queue的情况,你必须设置优先级,并且注册AVAudioSessionInterruptionNotification.以使你的app正确的响应.
系统如何处理音频资源的争夺
当你的iOS app启动的时候,很多系统内置的app,例如信息,音乐播放器,safari,电话.可能都在后台运行,其中的任意一个都有可能在制造audio,例如,新信息来的时候,你十分钟前启动的podcast任然在播放.诸如此类.
如果你把你的iOS设备看做一个飞机场,每一个app都看做一个飞机,那么操作系统可以被看做一个调度塔,用来控制每个音频的调度顺序.如图.
需要记住的是,系统永远遵循一个原则,就是电话的优先级最高.
使用AVCaptureSession
AVFoundation框架(AVCaptureDevice,AVCaptureSession)允许你同步的使用麦克分和摄像头捕捉音频和视
频.在iOS7系统,AVCaptureDevice对象,例如麦克风可以共享你的AVAudioSession配置.默认情况
下,AVCaptureSession会优化你的AVAudioSession以便于使用麦克风录制音频.如果把automaticallyConfiguresApplicationAudioSession
这个属性设置为NO,那么AVCaptureDevice不会修改你AVAudioSession的当前设置.
初始化你的Audio Session
系统在你的app加载之前就提供了一个audio session.但是,你任然需要初始化一个session用来处理各种中断事件.
AVFoundation Framework利用一个隐式的初始化方法来获取中断.你可以这样获取一个AVAudioSession的实例.
// implicitly initializes your audio session
AVAudioSession *session = [AVAudioSession sharedInstance];
变量session就代表了一个初始化的audio session,你可以直接使用.你可以使用AVAudioSession这个类提供的中断通知来处理各种音频的中断事件.并且系统提供了AVAudioPlayer和AVAudioRecorder的代理.
添加音量控制和路径控制
使用MPVolumeView
类可以显示声音和路径控制.音量view提供了一个滑动条去控制音量大小.并且提供了一个按钮来选择音频输出的路径.苹果推荐使用MPVolumeView
选择音频的出口.
远程控制
当你的app处于正在播放状态的时候,你可以远程控制你的app.详情查阅.Remote Control Events和MPNowPlayingInfoCenter Class Reference
激活和关闭你的AudioSession
系统虽然会在你的app加载的时候就激活你的audiosession.但是苹果还是推荐你显式的在你的viewDidLoad里激活你的audiosession.
NSError *activationError = nil;
BOOL success = [[AVAudioSession sharedInstance] setActive: YES error: &activationError];
if (!success) { /* handle the error in activationError */ }
检测app加载的时候是否有其他音频正在播放
使用otherAudioPlaying
属性可以检测是否有其他音频正在播放.