一、Audio Session的默认行为
- 可以播放,但不能进行录制;
- 静音开关设置为静音模式的时候,这个App的任何的音频播放都会被设置为静音;
- 当设备锁屏时,这个app的音频会被静音;
- 当App播放音频时,其他在后台播放的音频都会被静音;
二、配置Audio Session
在categories设置了Audio最基本的行为的同时,可以通过设置category的mode更进一步的设置Audio的行为。例如拥有Voice over IP (VoIP)功能的App,它会在使用AVAudioSessionCategoryPlayAndRecord
的同时,将Audio Session的mode也设置为AVAudioSessionModeVoiceChat
,这样可以通过系统级别的数字信号处理使音频信号得到提升。
某些categories支持使用设置options重写category默认的Audio行为,举例来讲,Category为AVAudioSessionCategoryPlayback
的Audio Session 在active的时候,会打断系统其他的Audio,大多数场景我们都需要这样的表现,但是如果想和系统其他音频进行混播,可以通过设置Category的options为AVAudioSessionCategoryOptionMixWithOthers
来进行实现,使用的方法为 setCategory:mode:options:error:
。
三、冲突的音频需求
同一时间内可能有多个app需要使用Audio device,系统这里做了一个比较形象的比。将使用Audio Device比作机场的跑道,将app比作正在飞机,系统服务作为塔台:
图中,第一步,你的App请求激活audio session;第二步,系统会判断你配置的category,这里你的app要求其他App进行静音;第三步和第四部,系统deactivates了音乐App的Audio Session,停止了它的音频播放;最后,系统激活了你的audio session,然后你就可以开始播放了;
四、Audio Session的激活和释放
虽然AVFoundation的播放和录音会自动激活Audio Session,但是手动激活可以让你知道active audio session是否成功。
闹钟、来电或者日历提醒的时候,系统会将你的App deactive掉,当用户dismiss或者挂断电话后,系统允许app再次active audio session,这个时候你可以决定是否将自己的AudioSession进行激活。
激活AudioSession的方法如下
1 | // Configure your audio session category, options, and mode |
可以将setActive
的参数设置为NO来释放AudioSession。除了一些VoIP、录音这些App,大多数App并不需要对AudioSession进行显式的释放。
对拥有VoIP功能的App,要确保在后台待机运行的情况下不激活AudioSession,确保只有收到呼叫的时候才激活AudioSession;
对于使用recording category的App,要确保只有它在录音的时候才处于激活状态。在录音前和录音结束后,要将AudioSession设置为未激活态,这样其他功能的音频提示、消息才能被正确播放出来;
五、处理中断
为了让App的可以在AudioSesson被电话呼叫、闹钟和其他App的Active事件打断后正常工作,我们需要去监听AudioSession的打断事件。音频的打断来自于那些被激活且未配置mix with others的AudioSession,打断会使我们的AudioSession处于未激活状态,然后结束我们对Audio的使用。
以上图片演示了一个播放应用程序的AudioSessionz在中断之前、期间和之后的事件序列。
可以使用AVAudioSessionInterruptionNotification
来监听AudioSession的变化:
1 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInterruption:) name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]]; |
在interrupt begin和interrupt end的时候做对应处理,当interruptType为AVAudioSessionInterruptionTypeEnded
时,可以从userInfo中通过AVAudioSessionInterruptionOptionKey
拿到option,当option的值为AVAudioSessionInterruptionOptionShouldResume
时,可以重新激活AudioSession并开始进行record或者play。
1 | - (void)handleInterruption:(NSNotification *)notification { |
六、响应媒体服务重置
媒体服务通过共享服务进程来提供音频和其他多媒体功能。虽然很罕见,但是在你的App处于active的时候,媒体服务重置的情况还是有可能发生的。可以通过注册 AVAudioSessionMediaServicesWereResetNotification
来监听媒体服务被重置的情况。当这种情况发生时,你需要做一些处理:
- 清理之前的audio对象(例如players、recorders、converters和audio queue),重新创建一个新的;
- 重置所有正在跟踪的内部音频状态,包括AVAudioSession的所有属性;
- 适当时,使用setActive:error:方法重新激活AVAudioSession实例;
Apps 无需重新注册AudioSession的notification,无需对AudioSession的属性进行 key-value 监控进行重置;