使用Audio Session API ,能够指定App须要的音频行为,好比,当播放音频时,使得其余应用App静音或者混和在一块儿,也能够指定当App的音频被中断(例如被电话)时的行为,还可让App响应用户的行为,好比插入或拔出耳机,或者响应那些使用声音硬件的事件,好比Clock、日历闹钟或者来电。
from Multimedia Programming Guide
编程
1. Audio Session 基础api
1.1 概述session
使用Audio Session API ,能够指定App须要的音频行为,好比,当播放音频时,使得其余应用App静音或者混和在一块儿,也能够指定当App的音频被中断(例如被电话)时的行为,还可让App响应用户的行为,好比插入或拔出耳机,或者响应那些使用声音硬件的事件,好比Clock、日历闹钟或者来电。app
(from Multimedia Programming Guide)框架
1.2 关于 Audio Session Categoryide
每一个category都是一个key,表明应用的一组audio行为。iOS中定义了6个category,每一个里面都有一组能够修改的开关,从而能够定制app的audio行为。函数
每一个category针对下面的每种行为设置了一个YES或者NO:优化
是否容许混音ui
是否在按下静音按钮或者锁屏时静音对象
是否支持音频输入
是否支持音频输出
这六个category分别是:
AVAudioSessionCategoryAmbient
AVAudioSessionCategorySoloAmbient
AVAudioSessionCategoryPlayback
AVAudioSessionCategoryRecord
AVAudioSessionCategoryPlayAndRecord
AVAudioSessionCategoryAudioProcessing
category不能自定义,可是能够修改里面的属性。
在不一样的时间能够设置不一样的category。
1.3 Audio Session的默认行为
默认的category是AVAudioSessionCategoryAmbient,此时的行为是:
支持播放
不支持录音
用户按下静音按钮时app静音
用户按下锁屏按钮时或者自动锁屏时,app静音
应用启动时,其余app静音
当app使用System Sound Services 或者UIKit playInputClick播放短音频时,能够忽略Audio Session处理
1.4 两种Audio Session API
一个是AVAudioSession类,一个是Audio Session Services,即一组C函数,前者使用更方便,后者能够对category的标准行为进行修改,这两组API能够混合使用。
2. 配置Audio Session
2.1 初始化Audio Session对象
若是使用AV Foundation framework 来管理中断, 那么使用
AVAudioSession *session = [AVAudioSession sharedInstance]来初始化session。
若是是本身写一个C函数来处理音频中断,那么使用AudioSessionInitialize来初始化session。
2.2 使得Audio Session活跃和非活跃
app系统时,系统激活app的audio session。当来电或者闹钟响起时,系统使得app的audio session非活跃。当挂电话或者忽略电话时,系统容许app的audio session再次活跃,为了从新激活,须要在处理中断的代码里面使得audio工做。
当使用AVAudioRecorder或者AVAudioPlayer时,系统会在中断处理代码里面使得audio session从新激活。而后,苹果建议在AVAudioSessionDelegate 的delegate函数里面显式地从新激活本身的audio session,从而确保激活成功。
2.3 选择最佳的category
iOS有6个audio session category,三个用于播放,一个用于录音,一个用于录音及播放,一个用于离线音频处理。(详细内容参见Audio Session Programming Guide)
2.4 不一样的category会影响编解码
若是覆盖了某个不支持mix的category,将不能使用硬件解码。
2.5 对Category进行微调
能够对audio session category使用不一样方法进行微调。
设置audio session的kAudioSessionProperty_OverrideCategoryMixWithOthers属性,能够覆盖本来不支持mix的category,如AVAudioSessionCategoryPlayback和AVAudioSessionCategoryPlayAndRecord,当容许混音后,将不能使用硬件编解码。
可使用编程方式影响音频输出路由,当使用AVAudioSessionCategoryPlayAndRecord时,音频一般从听筒里输出,能够进行覆盖来使得音频从扬声器输出。
3. 处理Audio Session中断
当遇到中断时,app会shut down,这一般发送在用户接电话时,若是用户选择拒绝电话或者挂掉闹钟,系统触发一个中断结束消息,并使app继续运行,当app恢复运行是,app的audio session须要被激活。
3.1 中断处理技术
两种方式:
(1)实现一个OC 的delegate函数
(2)写一个声明在Audio Session Services中的C函数。
如下是处理中断时须要的工做
After interruption starts
Check whether resumption of audio process is supported
Save state and context
Update user interface
After interruption ends
Restore state and context
Ractivate audio session
Update user interface
当使用AVAudioPlayer或者AVAudioRecorder,系统会自动处理某些工做。
对于不一样的音频框架,有不一样的音频中断处理技术:
AVFoundation AVAudioPlayer and AVAudioRecorder 提供了中断开始和结束的delegate函数
Audio Queue Services, I/O audio unit 实现 AVAudioSessionDelegate的函数来处理中断
3.2 中断的生存期
3.3 使用delegate函数来处理中断
AVAudioSessionDelegate提供了beginInterruption 和endInterruption
AVFoundation提供了下列delegate 函数
audioPlayerBeginInterruption
audioPlayerEndInterruption
audioRecorderBeginInterruption
audioRecorderEndInterruption:
3.4 使用callback函数来处理中断
可使用Audio Session Service里面的C api来注册一个AudioSessionInterruptionListener类型的回调函数处理中断
3.5 硬件辅助的编解码器和音频中断
4. 处理音频硬件路由变化
定义一个回调函数
将回调函数注册到audio session 便可对路由改变事件进行响应
5.对硬件设备的优化
6.与Movies和iPod Music协同工做
7.Audio Session 手册
7.1 初始化audio session
AudioSessionInitialize 或者AVAudioSession *session = [AVAudioSession sharedInstance];
7.2 使激活/使非激活session
NSError *activationError = nil;
BOOL success = [[AVAudioSession sharedInstance] setActive: YES error: &activationError];
if (!success) { /* handle the error in activationError */ }
或者
OSStatus activationResult = NULL;
result = AudioSessionSetActive (true);
7.3 设置category
NSError *setCategoryError = nil;
BOOL success = [[AVAudioSession sharedInstance]
setCategory: AVAudioSessionCategoryAmbient
error: &setCategoryError];
if (!success) { /* handle the error in setCategoryError */ }
或者
UInt32 sessionCategory = kAudioSessionCategory_AmbientSound; // 1
AudioSessionSetProperty (
kAudioSessionProperty_AudioCategory, // 2
sizeof (sessionCategory), // 3
&sessionCategory // 4
);
7.4 检查app启动时是否有其余app在播放音频
UInt32 otherAudioIsPlaying; // 1
UInt32 propertySize = sizeof (otherAudioIsPlaying);
AudioSessionGetProperty ( // 2
kAudioSessionProperty_OtherAudioIsPlaying,
&propertySize,
&otherAudioIsPlaying
);
if (otherAudioIsPlaying) { // 3
[[AVAudioSession sharedInstance]
setCategory: AVAudioSessionCategoryAmbient
error: nil];
} else {
[[AVAudioSession sharedInstance]
setCategory: AVAudioSessionCategorySoloAmbient
error: nil];
}
7.5 修改播放混音行为
OSStatus propertySetError = 0;
UInt32 allowMixing = true;
propertySetError = AudioSessionSetProperty (
kAudioSessionProperty_OverrideCategoryMixWithOthers, // 1
sizeof (allowMixing), // 2
&allowMixing // 3
);
7.6 优化电量消耗
7.7 优化低延迟
7.8 改变输出路由
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker; // 1
AudioSessionSetProperty (
kAudioSessionProperty_OverrideAudioRoute, // 2
sizeof (audioRouteOverride), // 3
&audioRouteOverride // 4
);
7.9 对audio session 中断做出相应
7.10 对音频硬件路由改变事件进行响应(路由改变事件指用户插入或拔出耳机,将手机插上dock或者拨出dock)
定义一个回调函数
将回调函数注册到audio session 便可对路由改变事件进行响应
7.11 查询音频硬件特性
能够设置音频硬件的采样率以及io buffer duration
查询设备是否支持录音
#if TARGET_IPHONE_SIMULATOR判断是不是在模拟器上运行