AVAudioSession(3):定制 Audio Session 的 Category

本文轉自:AVAudioSession(3):定制 Audio Session 的 Category | www.samirchen.com

本文內容主要來源于 Working with Categories

對于 Audio Session 來說,與之對應的 Category 是闡釋其音頻行為的關鍵信息。比如:你的 App 的聲音是否應該受到手機的靜音鍵的控制、你的 App 使不使用音頻輸入或輸出、其他音樂能否和你的 Audio 共存播放等等。

每一種 Category 都指定了是否支持下列這些能力:

  • Interrupts non-mixable apps audio:是否打斷不支持混音播放的應用。如果是,則當你的應用的音頻開始播放時,則那些不支持混音播放的應用的音頻會被打斷。
  • Silenced by the Silent switch:是否響應手機靜音鍵。如果是,則當手機靜音鍵被撥至靜音狀態時,你的音頻會被靜音。
  • Supports audio input:是否支持音頻輸入。如果是,你的應用就可以錄音。
  • Supports audio output:是否支持音頻輸出。如果是,你的應用就可以播放音頻。

下面是各種 Category 的能力表格:

Category 是否會被靜音鍵或鎖屏鍵靜音 是否打斷不支持混音播放的應用 是否允許音頻輸入/輸出
AVAudioSessionCategoryAmbient Yes NO 只輸出
AVAudioSessionCategoryAudioProcessing - YES 無輸入和輸出
AVAudioSessionCategoryMultiRoute NO YES 支持輸入和輸出
AVAudioSessionCategoryPlayAndRecord NO 默認 YES,可重寫開關置為 NO 支持輸入和輸出
AVAudioSessionCategoryPlayback NO 默認 YES,可重寫開關置為 NO 只輸出
AVAudioSessionCategoryRecord NO(鎖屏時依然保持錄制) YES 只輸入
AVAudioSessionCategorySoloAmbient YES YES 只輸出

大部分應用只需要在啟動時設置一下 Category 即可,不過你是可以隨時修改 Audio Session 的 Category,也可以隨時激活和關閉 Audio Session。當你的 Audio Session 是 Inactive 的,Category 的請求會在你激活它時發送,如果是 Active 的,則立即發送。

選擇最合適的 Category

每一種 Category 最準確的行為定義是由系統控制而不是你的應用,蘋果可能會在將來重新定義不同的 Category 的行為,所以你最好是選擇一種與你的應用使用音頻方式匹配的 Category 來用。

下面列一下各種 Category 的使用場景:

  • AVAudioSessionCategoryAmbient,只支持音頻播放。適用于把音頻作為輔助性元素而非不可獲取特性的應用,使用這個 Category,你的音頻會被靜音鍵和鎖屏鍵靜音。

  • AVAudioSessionCategorySoloAmbient,這個是默認使用的 Category,只支持音頻播放。音頻會被靜音鍵和鎖屏鍵靜音。這個 Category 和 AVAudioSessionCategoryAmbient 的唯一不同在于它會打斷其他應用的音頻播放。

  • AVAudioSessionCategoryPlayback,只支持音頻播放。你的音頻不會被靜音鍵和鎖屏鍵靜音。當你的應用把音頻播放作為重要功能時,你可以使用這個 Category。

有一點需要注意的是,當你選擇那些支持在靜音鍵切到靜音狀態以及鎖屏鍵切到鎖屏狀態下仍然支持你的音頻繼續播放的 Category 時,你必須在你的應用中開啟 Background Audio 的能力,詳見 UIBackgroundModes。并且,通常你不應該通過 idleTimerDisabled 接口關閉系統的 Sleep Timer。如果你關閉了,那你應該把 idleTimerDisabled 置回 NO,以免你的應用會禁止自動屏幕鎖定,畢竟鎖屏并不會影響你的音頻播放,你干嘛關閉它呢。Sleep Timer 可以確保你的屏幕在用戶無操作一段時間后自動變暗并鎖定來省電。

  • AVAudioSessionCategoryRecord,只支持音頻錄制。如果你的應用既要錄制還要播放,那你應該用 AVAudioSessionCategoryPlayAndRecord。
  • AVAudioSessionCategoryPlayAndRecord,支持音頻播放和錄制。音頻的輸入和輸出不需要同步進行,當然也可以同步進行。對于音頻通話類應用,可以使用這個 Category。
  • AVAudioSessionCategoryAudioProcessing,只支持離線音頻處理。支持離線音頻處理,并且不支持播放和錄制。
  • AVAudioSessionCategoryMultiRoute,支持音頻播放和錄制。允許多條音頻流的同步輸入和輸出。比如:USB 和耳麥同時音頻輸出。

除了 AVAudioSessionCategoryMultiRoute 外,其他的 Category 都遵循 last in wins 原則,即最后接入的音頻設備作為輸入或輸出的主設備。

使用 AVAudioSessionCategoryMultiRoute 來擴展音頻選擇

AVAudioSessionCategoryMultiRoute 并不是簡單的遵循 last in wins 原則,AVAudioSessionCategoryMultiRoute 允許你的使用所有連接的輸出接口而不僅是最后連上的接口。比如,當你正在通過 HDMI 輸出路徑聽音頻,這時又插上了耳麥,你的應用可以同時在 HDMI 和耳麥都輸出音頻。

在 AVAudioSessionCategoryMultiRoute 下,你的應用可以發送不同的音頻流到不同的輸出路徑。例如,你的應用可以將一條音頻流發送到你的左耳麥,另一條音頻流發送到右耳麥,并將第三條流發送到 HDMI 路徑。如下圖所示:

image

AVAudioSessionCategoryMultiRoute 支持下列輸出組合:

  • USB + 耳麥
  • HDMI + 耳麥
  • LineOut + 耳麥

AVAudioSessionCategoryMultiRoute 支持單輸入接口。

設置 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 可以定制應用的音頻行為,我們使用 Mode 則可以定制 Category 的行為。可選的 Mode 有這些:

Mode 兼容的 Category
AVAudioSessionModeDefault All
AVAudioSessionModeVoiceChat AVAudioSessionCategoryPlayAndRecord
AVAudioSessionModeGameChat AVAudioSessionCategoryPlayAndRecord
AVAudioSessionModeVideoRecording AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryRecord
AVAudioSessionModeMoviePlayback AVAudioSessionCategoryPlayback
AVAudioSessionModeMeasurement AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryRecord AVAudioSessionCategoryPlayback
AVAudioSessionModeVideoChat AVAudioSessionCategoryPlayAndRecord

除了這些 Mode 外,有時在定制你的 Category 時,你還需要使用到一些 Option:

Option 說明 兼容的 Category
AVAudioSessionCategoryOptionMixWithOthers 允許和其他音頻 mix AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryPlayback AVAudioSessionCategoryMultiRoute
AVAudioSessionCategoryOptionDuckOthers 智能調低沖突音頻音量 AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryPlayback AVAudioSessionCategoryMultiRoute
AVAudioSessionCategoryOptionAllowBluetooth 允許藍牙音頻輸入 AVAudioSessionCategoryRecord AVAudioSessionCategoryPlayAndRecord
AVAudioSessionCategoryOptionDefaultToSpeaker 默認輸出音頻到揚聲器 AVAudioSessionCategoryPlayAndRecord
  • AVAudioSessionModeDefault,默認模式可以與所有的 Category 兼容使用,并配置設備用于一般用途。

  • AVAudioSessionModeVoiceChat,一般用于 VoIP 類型的應用。這個模式只用于 AVAudioSessionCategoryPlayAndRecord Category。在這個模式下,用于音頻的信號會由系統提供的信號處理程序優化,并且這個模式會配置上 AVAudioSessionCategoryOptionAllowBluetooth 這個選項。這個設置下,當系統內置麥克風被使用時,系統會自動選擇最佳內置麥克風組合支持語音聊天,從而優化語音聊天體驗。

  • AVAudioSessionModeVideoChat,一般用于視頻聊天應用,比如 FaceTime。這個模式只用于 AVAudioSessionCategoryPlayAndRecord Category。在這個模式下,用于音頻的信號會由系統提供的信號處理程序優化,并且這個模式會配置上 AVAudioSessionCategoryOptionAllowBluetooth 和 AVAudioSessionCategoryOptionDefaultToSpeaker 選項。這個設置下,當系統內置麥克風被使用時,系統會自動選擇最佳內置麥克風組合支持視頻聊天,從而優化視頻聊天體驗。

蘋果推薦音頻或視頻聊天應用也使用 Voice-Processing I/O Unit,這個模塊提供了一系列的特性來支持 VoIP 類應用。

  • AVAudioSessionModeGameChat,一般用于游戲類應用。使用 GKVoiceChat 對象的應用會自動設置這個模式和 AVAudioSessionCategoryPlayAndRecord Category。這個模式使用的路徑參數和 AVAudioSessionModeVideoChat 一致。

  • AVAudioSessionModeVideoRecording,一般用于需要使用攝像頭采集視頻的應用。這個模式只用于 AVAudioSessionCategoryPlayAndRecord 和 AVAudioSessionCategoryRecord 這兩個 Category。在這個模式下,信號會被系統提供的信號處理程序修改。這個模式與 AVCaptureSession API 結合來用可以更好地控制音視頻的輸入輸出路徑。比如,通過設置 automaticallyConfiguresApplicationAudioSession 屬性可以讓系統根據所使用的設備自動選擇最佳輸出路徑。

  • AVAudioSessionModeMeasurement,一般用于那些要最小化系統自帶的音視頻信號處理流程對信號的影響的應用。這個模式只用于 AVAudioSessionCategoryPlayAndRecord、AVAudioSessionCategoryRecord、AVAudioSessionCategoryPlayback 這幾種 Category。輸入信號由設備的主麥克風來路由。

  • AVAudioSessionModeMoviePlayback,一般用于播放電影或其他視頻的應用。這個模式只用于 AVAudioSessionCategoryPlayback Category。

支持 AirPlay 的 Category 和 Mode

以下 Category 支持「鏡像」和「非鏡像」版本的 AirPlay:

  • AVAudioSessionCategorySoloAmbient
  • AVAudioSessionCategoryAmbient
  • AVAudioSessionCategoryPlayback

此外:

  • AVAudioSessionCategoryPlayAndRecord 只支持「鏡像」版本的 AirPlay。

Mode 只有在和 AVAudioSessionCategoryPlayAndRecord Category 配合使用時才支持 AirPlay,下面的 Mode 只支持「鏡像」版本的 AirPlay:

  • AVAudioSessionModeDefault
  • AVAudioSessionModeVideoChat
  • AVAudioSessionModeGameChat

Category 使用調優

你可以有多種方式來調優 Category,下面舉幾個例子:

  • 允許其他 App 的音頻與你的音頻 mix 在一起播放。你可以改寫 AVAudioSessionCategoryPlayback、AVAudioSessionCategoryPlayAndRecord、AVAudioSessionCategoryMultiRoute 這些 Category 的中斷特性。改寫時,你需要應用 AVAudioSessionCategoryOptionMixWithOthers 選項到你的 Audio Session。如果你的應用是 mixable 的,當一個 non-mixable 應用的 Audio Session 被激活時,你的應用不會中斷它的音頻。同樣,你的應用的音頻在播放時也不會被其他 non-mixable 的應用中斷。
  • 將音頻輸出路徑從聽筒改到揚聲器。當你使用 AVAudioSessionCategoryPlayAndRecord 這個 Category 時,音頻默認是從聽筒輸出的,你可以通過 overrideOutputAudioPort:error: 方法將音頻輸出路徑改到揚聲器。
  • 當你的音頻播放時,你可以強制其他的音頻降低音量。這時候你需要將 AVAudioSessionCategoryOptionDuckOthers 應用到你的 Category 上,使用這個特性的應用需要管理自己的 Audio Session,在播放音頻前激活 Audio Session,在播放完成后關閉 Audio Session。

音頻錄制權限申請

從 iOS7 之后,錄制音頻的權限需要用戶授權才能獲得。如果用戶不給你權限,那么你錄制的就是靜音。當你使用一個需要錄制權限的 Category 來定制你的 Audio Session 時,系統會自動彈出權限申請提示給用戶。

除了讓系統自動彈出權限申請提示外,你還可以通過 requestRecordPermission: 方法來向用戶請求權限。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,488評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,034評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,327評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,554評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,337評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,883評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,114評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,625評論 1 332
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,555評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,737評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,973評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,615評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,343評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,699評論 2 370

推薦閱讀更多精彩內容