使用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判斷是不是在模擬器上運行