AVAudioSession(3):定制 Audio Session 的 Category

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

本文內(nèi)容主要來源于 Working with Categories

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

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

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

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

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

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

選擇最合適的 Category

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

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

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

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

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

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

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

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

使用 AVAudioSessionCategoryMultiRoute 來擴展音頻選擇

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

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

image

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 可以定制應用的音頻行為,我們使用 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 智能調(diào)低沖突音頻音量 AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryPlayback AVAudioSessionCategoryMultiRoute
AVAudioSessionCategoryOptionAllowBluetooth 允許藍牙音頻輸入 AVAudioSessionCategoryRecord AVAudioSessionCategoryPlayAndRecord
AVAudioSessionCategoryOptionDefaultToSpeaker 默認輸出音頻到揚聲器 AVAudioSessionCategoryPlayAndRecord
  • AVAudioSessionModeDefault,默認模式可以與所有的 Category 兼容使用,并配置設(shè)備用于一般用途。

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

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

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

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

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

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

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

支持 AirPlay 的 Category 和 Mode

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

  • AVAudioSessionCategorySoloAmbient
  • AVAudioSessionCategoryAmbient
  • AVAudioSessionCategoryPlayback

此外:

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

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

  • AVAudioSessionModeDefault
  • AVAudioSessionModeVideoChat
  • AVAudioSessionModeGameChat

Category 使用調(diào)優(yōu)

你可以有多種方式來調(diào)優(yōu) 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,在播放完成后關(guān)閉 Audio Session。

音頻錄制權(quán)限申請

從 iOS7 之后,錄制音頻的權(quán)限需要用戶授權(quán)才能獲得。如果用戶不給你權(quán)限,那么你錄制的就是靜音。當你使用一個需要錄制權(quán)限的 Category 來定制你的 Audio Session 時,系統(tǒng)會自動彈出權(quán)限申請?zhí)崾窘o用戶。

除了讓系統(tǒng)自動彈出權(quán)限申請?zhí)崾就猓氵€可以通過 requestRecordPermission: 方法來向用戶請求權(quán)限。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容