本文轉(zhuǎn)自:AVAudioSession(3):定制 Audio Session 的 Category | www.samirchen.com
本文內(nèi)容主要來源于 Working with Categories。
對(duì)于 Audio Session 來說,與之對(duì)應(yīng)的 Category 是闡釋其音頻行為的關(guān)鍵信息。比如:你的 App 的聲音是否應(yīng)該受到手機(jī)的靜音鍵的控制观堂、你的 App 使不使用音頻輸入或輸出洒缀、其他音樂能否和你的 Audio 共存播放等等艰山。
每一種 Category 都指定了是否支持下列這些能力:
-
Interrupts non-mixable apps audio
:是否打斷不支持混音播放的應(yīng)用醉锅。如果是侣签,則當(dāng)你的應(yīng)用的音頻開始播放時(shí)芥玉,則那些不支持混音播放的應(yīng)用的音頻會(huì)被打斷蛇摸。 -
Silenced by the Silent switch
:是否響應(yīng)手機(jī)靜音鍵。如果是灿巧,則當(dāng)手機(jī)靜音鍵被撥至靜音狀態(tài)時(shí)赶袄,你的音頻會(huì)被靜音。 -
Supports audio input
:是否支持音頻輸入抠藕。如果是饿肺,你的應(yīng)用就可以錄音。 -
Supports audio output
:是否支持音頻輸出盾似。如果是敬辣,你的應(yīng)用就可以播放音頻。
下面是各種 Category 的能力表格:
Category | 是否會(huì)被靜音鍵或鎖屏鍵靜音 | 是否打斷不支持混音播放的應(yīng)用 | 是否允許音頻輸入/輸出 |
---|---|---|---|
AVAudioSessionCategoryAmbient | Yes | NO | 只輸出 |
AVAudioSessionCategoryAudioProcessing | - | YES | 無輸入和輸出 |
AVAudioSessionCategoryMultiRoute | NO | YES | 支持輸入和輸出 |
AVAudioSessionCategoryPlayAndRecord | NO | 默認(rèn) YES零院,可重寫開關(guān)置為 NO | 支持輸入和輸出 |
AVAudioSessionCategoryPlayback | NO | 默認(rèn) YES溉跃,可重寫開關(guān)置為 NO | 只輸出 |
AVAudioSessionCategoryRecord | NO(鎖屏?xí)r依然保持錄制) | YES | 只輸入 |
AVAudioSessionCategorySoloAmbient | YES | YES | 只輸出 |
大部分應(yīng)用只需要在啟動(dòng)時(shí)設(shè)置一下 Category 即可,不過你是可以隨時(shí)修改 Audio Session 的 Category告抄,也可以隨時(shí)激活和關(guān)閉 Audio Session撰茎。當(dāng)你的 Audio Session 是 Inactive 的,Category 的請(qǐng)求會(huì)在你激活它時(shí)發(fā)送打洼,如果是 Active 的龄糊,則立即發(fā)送。
選擇最合適的 Category
每一種 Category 最準(zhǔn)確的行為定義是由系統(tǒng)控制而不是你的應(yīng)用募疮,蘋果可能會(huì)在將來重新定義不同的 Category 的行為炫惩,所以你最好是選擇一種與你的應(yīng)用使用音頻方式匹配的 Category 來用。
下面列一下各種 Category 的使用場景:
AVAudioSessionCategoryAmbient阿浓,只支持音頻播放诡必。適用于把音頻作為輔助性元素而非不可獲取特性的應(yīng)用,使用這個(gè) Category搔扁,你的音頻會(huì)被靜音鍵和鎖屏鍵靜音爸舒。
AVAudioSessionCategorySoloAmbient,這個(gè)是默認(rèn)使用的 Category稿蹲,只支持音頻播放扭勉。音頻會(huì)被靜音鍵和鎖屏鍵靜音。這個(gè) Category 和 AVAudioSessionCategoryAmbient 的唯一不同在于它會(huì)打斷其他應(yīng)用的音頻播放苛聘。
AVAudioSessionCategoryPlayback涂炎,只支持音頻播放忠聚。你的音頻不會(huì)被靜音鍵和鎖屏鍵靜音。當(dāng)你的應(yīng)用把音頻播放作為重要功能時(shí)唱捣,你可以使用這個(gè) Category两蟀。
有一點(diǎn)需要注意的是,當(dāng)你選擇那些支持在靜音鍵切到靜音狀態(tài)以及鎖屏鍵切到鎖屏狀態(tài)下仍然支持你的音頻繼續(xù)播放的 Category 時(shí)震缭,你必須在你的應(yīng)用中開啟 Background Audio 的能力赂毯,詳見 UIBackgroundModes。并且拣宰,通常你不應(yīng)該通過 idleTimerDisabled 接口關(guān)閉系統(tǒng)的 Sleep Timer党涕。如果你關(guān)閉了,那你應(yīng)該把 idleTimerDisabled 置回 NO巡社,以免你的應(yīng)用會(huì)禁止自動(dòng)屏幕鎖定膛堤,畢竟鎖屏并不會(huì)影響你的音頻播放,你干嘛關(guān)閉它呢晌该。Sleep Timer 可以確保你的屏幕在用戶無操作一段時(shí)間后自動(dòng)變暗并鎖定來省電肥荔。
- AVAudioSessionCategoryRecord,只支持音頻錄制朝群。如果你的應(yīng)用既要錄制還要播放燕耿,那你應(yīng)該用 AVAudioSessionCategoryPlayAndRecord。
- AVAudioSessionCategoryPlayAndRecord潜圃,支持音頻播放和錄制缸棵。音頻的輸入和輸出不需要同步進(jìn)行,當(dāng)然也可以同步進(jìn)行谭期。對(duì)于音頻通話類應(yīng)用堵第,可以使用這個(gè) Category肛走。
- AVAudioSessionCategoryAudioProcessing赞咙,只支持離線音頻處理。支持離線音頻處理宿饱,并且不支持播放和錄制胀瞪。
- AVAudioSessionCategoryMultiRoute针余,支持音頻播放和錄制。允許多條音頻流的同步輸入和輸出凄诞。比如:USB 和耳麥同時(shí)音頻輸出圆雁。
除了 AVAudioSessionCategoryMultiRoute 外,其他的 Category 都遵循 last in wins 原則帆谍,即最后接入的音頻設(shè)備作為輸入或輸出的主設(shè)備伪朽。
使用 AVAudioSessionCategoryMultiRoute 來擴(kuò)展音頻選擇
AVAudioSessionCategoryMultiRoute 并不是簡單的遵循 last in wins 原則,AVAudioSessionCategoryMultiRoute 允許你的使用所有連接的輸出接口而不僅是最后連上的接口汛蝙。比如烈涮,當(dāng)你正在通過 HDMI 輸出路徑聽音頻朴肺,這時(shí)又插上了耳麥,你的應(yīng)用可以同時(shí)在 HDMI 和耳麥都輸出音頻坚洽。
在 AVAudioSessionCategoryMultiRoute 下戈稿,你的應(yīng)用可以發(fā)送不同的音頻流到不同的輸出路徑。例如讶舰,你的應(yīng)用可以將一條音頻流發(fā)送到你的左耳麥鞍盗,另一條音頻流發(fā)送到右耳麥,并將第三條流發(fā)送到 HDMI 路徑绘雁。如下圖所示:
AVAudioSessionCategoryMultiRoute 支持下列輸出組合:
- USB + 耳麥
- HDMI + 耳麥
- LineOut + 耳麥
AVAudioSessionCategoryMultiRoute 支持單輸入接口橡疼。
設(shè)置 Audio Session Category
代碼如下:
NSError *setCategoryError = nil;
BOOL success = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:&setCategoryError];
// BOOL success = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers | AVAudioSessionCategoryOptionDuckOthers error:&setCategoryError];
if (!success) { /* handle the error in setCategoryError */ }
使用 Mode 來定制 Category
正如使用 Category 可以定制應(yīng)用的音頻行為援所,我們使用 Mode 則可以定制 Category 的行為庐舟。可選的 Mode 有這些:
Mode | 兼容的 Category |
---|---|
AVAudioSessionModeDefault | All |
AVAudioSessionModeVoiceChat | AVAudioSessionCategoryPlayAndRecord |
AVAudioSessionModeGameChat | AVAudioSessionCategoryPlayAndRecord |
AVAudioSessionModeVideoRecording | AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryRecord |
AVAudioSessionModeMoviePlayback | AVAudioSessionCategoryPlayback |
AVAudioSessionModeMeasurement | AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryRecord AVAudioSessionCategoryPlayback |
AVAudioSessionModeVideoChat | AVAudioSessionCategoryPlayAndRecord |
除了這些 Mode 外住拭,有時(shí)在定制你的 Category 時(shí)挪略,你還需要使用到一些 Option:
Option | 說明 | 兼容的 Category |
---|---|---|
AVAudioSessionCategoryOptionMixWithOthers | 允許和其他音頻 mix | AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryPlayback AVAudioSessionCategoryMultiRoute |
AVAudioSessionCategoryOptionDuckOthers | 智能調(diào)低沖突音頻音量 | AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryPlayback AVAudioSessionCategoryMultiRoute |
AVAudioSessionCategoryOptionAllowBluetooth | 允許藍(lán)牙音頻輸入 | AVAudioSessionCategoryRecord AVAudioSessionCategoryPlayAndRecord |
AVAudioSessionCategoryOptionDefaultToSpeaker | 默認(rèn)輸出音頻到揚(yáng)聲器 | AVAudioSessionCategoryPlayAndRecord |
AVAudioSessionModeDefault,默認(rèn)模式可以與所有的 Category 兼容使用滔岳,并配置設(shè)備用于一般用途杠娱。
AVAudioSessionModeVoiceChat,一般用于 VoIP 類型的應(yīng)用谱煤。這個(gè)模式只用于 AVAudioSessionCategoryPlayAndRecord Category摊求。在這個(gè)模式下,用于音頻的信號(hào)會(huì)由系統(tǒng)提供的信號(hào)處理程序優(yōu)化刘离,并且這個(gè)模式會(huì)配置上 AVAudioSessionCategoryOptionAllowBluetooth 這個(gè)選項(xiàng)室叉。這個(gè)設(shè)置下,當(dāng)系統(tǒng)內(nèi)置麥克風(fēng)被使用時(shí)硫惕,系統(tǒng)會(huì)自動(dòng)選擇最佳內(nèi)置麥克風(fēng)組合支持語音聊天茧痕,從而優(yōu)化語音聊天體驗(yàn)。
AVAudioSessionModeVideoChat恼除,一般用于視頻聊天應(yīng)用踪旷,比如 FaceTime。這個(gè)模式只用于 AVAudioSessionCategoryPlayAndRecord Category豁辉。在這個(gè)模式下令野,用于音頻的信號(hào)會(huì)由系統(tǒng)提供的信號(hào)處理程序優(yōu)化,并且這個(gè)模式會(huì)配置上 AVAudioSessionCategoryOptionAllowBluetooth 和 AVAudioSessionCategoryOptionDefaultToSpeaker 選項(xiàng)徽级。這個(gè)設(shè)置下气破,當(dāng)系統(tǒng)內(nèi)置麥克風(fēng)被使用時(shí),系統(tǒng)會(huì)自動(dòng)選擇最佳內(nèi)置麥克風(fēng)組合支持視頻聊天灰追,從而優(yōu)化視頻聊天體驗(yàn)堵幽。
蘋果推薦音頻或視頻聊天應(yīng)用也使用 Voice-Processing I/O Unit狗超,這個(gè)模塊提供了一系列的特性來支持 VoIP 類應(yīng)用。
AVAudioSessionModeGameChat朴下,一般用于游戲類應(yīng)用努咐。使用 GKVoiceChat 對(duì)象的應(yīng)用會(huì)自動(dòng)設(shè)置這個(gè)模式和 AVAudioSessionCategoryPlayAndRecord Category。這個(gè)模式使用的路徑參數(shù)和 AVAudioSessionModeVideoChat 一致殴胧。
AVAudioSessionModeVideoRecording渗稍,一般用于需要使用攝像頭采集視頻的應(yīng)用。這個(gè)模式只用于 AVAudioSessionCategoryPlayAndRecord 和 AVAudioSessionCategoryRecord 這兩個(gè) Category团滥。在這個(gè)模式下竿屹,信號(hào)會(huì)被系統(tǒng)提供的信號(hào)處理程序修改。這個(gè)模式與 AVCaptureSession API 結(jié)合來用可以更好地控制音視頻的輸入輸出路徑灸姊。比如拱燃,通過設(shè)置 automaticallyConfiguresApplicationAudioSession 屬性可以讓系統(tǒng)根據(jù)所使用的設(shè)備自動(dòng)選擇最佳輸出路徑。
AVAudioSessionModeMeasurement力惯,一般用于那些要最小化系統(tǒng)自帶的音視頻信號(hào)處理流程對(duì)信號(hào)的影響的應(yīng)用碗誉。這個(gè)模式只用于 AVAudioSessionCategoryPlayAndRecord、AVAudioSessionCategoryRecord父晶、AVAudioSessionCategoryPlayback 這幾種 Category哮缺。輸入信號(hào)由設(shè)備的主麥克風(fēng)來路由。
AVAudioSessionModeMoviePlayback甲喝,一般用于播放電影或其他視頻的應(yīng)用尝苇。這個(gè)模式只用于 AVAudioSessionCategoryPlayback Category。
支持 AirPlay 的 Category 和 Mode
以下 Category 支持「鏡像」和「非鏡像」版本的 AirPlay:
- AVAudioSessionCategorySoloAmbient
- AVAudioSessionCategoryAmbient
- AVAudioSessionCategoryPlayback
此外:
- AVAudioSessionCategoryPlayAndRecord 只支持「鏡像」版本的 AirPlay埠胖。
Mode 只有在和 AVAudioSessionCategoryPlayAndRecord Category 配合使用時(shí)才支持 AirPlay糠溜,下面的 Mode 只支持「鏡像」版本的 AirPlay:
- AVAudioSessionModeDefault
- AVAudioSessionModeVideoChat
- AVAudioSessionModeGameChat
Category 使用調(diào)優(yōu)
你可以有多種方式來調(diào)優(yōu) Category,下面舉幾個(gè)例子:
- 允許其他 App 的音頻與你的音頻 mix 在一起播放押袍。你可以改寫 AVAudioSessionCategoryPlayback诵冒、AVAudioSessionCategoryPlayAndRecord、AVAudioSessionCategoryMultiRoute 這些 Category 的中斷特性谊惭。改寫時(shí)汽馋,你需要應(yīng)用 AVAudioSessionCategoryOptionMixWithOthers 選項(xiàng)到你的 Audio Session。如果你的應(yīng)用是 mixable 的圈盔,當(dāng)一個(gè) non-mixable 應(yīng)用的 Audio Session 被激活時(shí)豹芯,你的應(yīng)用不會(huì)中斷它的音頻。同樣驱敲,你的應(yīng)用的音頻在播放時(shí)也不會(huì)被其他 non-mixable 的應(yīng)用中斷铁蹈。
- 將音頻輸出路徑從聽筒改到揚(yáng)聲器。當(dāng)你使用 AVAudioSessionCategoryPlayAndRecord 這個(gè) Category 時(shí)众眨,音頻默認(rèn)是從聽筒輸出的握牧,你可以通過 overrideOutputAudioPort:error: 方法將音頻輸出路徑改到揚(yáng)聲器容诬。
- 當(dāng)你的音頻播放時(shí),你可以強(qiáng)制其他的音頻降低音量沿腰。這時(shí)候你需要將 AVAudioSessionCategoryOptionDuckOthers 應(yīng)用到你的 Category 上览徒,使用這個(gè)特性的應(yīng)用需要管理自己的 Audio Session,在播放音頻前激活 Audio Session颂龙,在播放完成后關(guān)閉 Audio Session习蓬。
音頻錄制權(quán)限申請(qǐng)
從 iOS7 之后,錄制音頻的權(quán)限需要用戶授權(quán)才能獲得措嵌。如果用戶不給你權(quán)限躲叼,那么你錄制的就是靜音。當(dāng)你使用一個(gè)需要錄制權(quán)限的 Category 來定制你的 Audio Session 時(shí)企巢,系統(tǒng)會(huì)自動(dòng)彈出權(quán)限申請(qǐng)?zhí)崾窘o用戶枫慷。
除了讓系統(tǒng)自動(dòng)彈出權(quán)限申請(qǐng)?zhí)崾就猓氵€可以通過 requestRecordPermission: 方法來向用戶請(qǐng)求權(quán)限包斑。