【轉】iOS 音頻-AVAudioSession

來源:互聯網
上載者:User

標籤:點擊   key   同步   音頻播放   player   success   路徑   競爭   apt   

1. AVAudioSession 概述

最近一年一直在做IPC Camera的iOS用戶端開發。和音頻打交道,必須要弄清楚
AVAudioSession。
先看下蘋果的官方圖:


 Audio Session

可以看到AVAudioSession就是用來管理多個APP對音頻硬體裝置(麥克風,擴音器)的資源使用。

舉例一下AVAudioSession可以做這些事情

  • 設定自己的APP是否和其他APP音頻同時存在,還是中斷其他APP聲音
  • 在手機調到靜音下,自己的APP音頻是否可以播放出聲音
  • 電話或者其他APP中斷自己APP的音訊事件處理
  • 指定音頻輸入和輸出的裝置(比如是耳機輸出聲音,還是擴音器輸出聲音)
  • 是否支援錄音,錄音同時是否支援音頻播放
2. AVAudioSession Category

AVAudioSession的介面比較簡單。APP啟動的時候會自動幫啟用AVAudioSession,當然我們可以手動啟用代碼如下。

    //匯入標頭檔    #import <AVFoundation/AVFoundation.h>    //AVAudioSession是一個單例類    AVAudioSession *session = [AVAudioSession sharedInstance];    //AVAudioSessionCategorySoloAmbient是系統預設的category    [session setCategory:AVAudioSessionCategorySoloAmbient error:nil];    //啟用AVAudioSession    [session setActive:YES error:nil];

可以看到設定session這裡有兩個參數,category和options
Category iOS下目前有七種,每種Category都對應是否支援下面四種能力

  • Interrupts non-mixable apps audio:是否打斷不支援混音播放的APP
  • Silenced by the Silent switch:是否會響應手機靜音鍵開關
  • Supports audio input:是否支援音頻錄製
  • Supports audio output:是否支援音頻播放

下面用圖表來直觀的看下每種category具體的能力集

Category 是否允許音頻播放/錄音 是否打斷其他不支援混音APP 是否會被靜音鍵或鎖屏鍵靜音
AVAudioSessionCategoryAmbient 只支援播放
AVAudioSessionCategoryAudioProcessing 不支援播放,不支援錄製
AVAudioSessionCategoryMultiRoute 支援播放,支援錄製
AVAudioSessionCategoryPlayAndRecord 支援播放,支援錄製 預設YES,可以重寫為NO
AVAudioSessionCategoryPlayback 只支援播放 預設YES,可以重寫為NO
AVAudioSessionCategoryRecord 只支援錄製 否(鎖屏下仍可錄製)
AVAudioSessionCategorySoloAmbient 只支援播放
  • AVAudioSessionCategoryAmbient,只支援音頻播放。這個 Category,音頻會被靜音鍵和鎖屏鍵靜音。並且不會打斷其他應用的音頻播放。

  • AVAudioSessionCategorySoloAmbient,這個是系統預設使用的 Category,只支援音頻播放。音頻會被靜音鍵和鎖屏鍵靜音。和AVAudioSessionCategoryAmbient不同的是,這個會打斷其他應用的音頻播放

  • AVAudioSessionCategoryPlayback,只支援音頻播放。你的音頻不會被靜音鍵和鎖屏鍵靜音。適用於音頻是主要功能的APP,像網易雲這些音樂app,鎖屏後依然可以播放。

需要注意一下,選擇支援在靜音鍵切到靜音狀態以及鎖屏鍵切到鎖屏狀態下仍然可以播放音頻 Category 時,必須在應用中開啟支援後台音頻功能,詳見 UIBackgroundModes。

  • AVAudioSessionCategoryRecord,只支援音頻錄製。不支援播放。
  • AVAudioSessionCategoryPlayAndRecord,支援音頻播放和錄製。音訊輸入和輸出不需要同步進行,也可以同步進行。需要語音通話類應用,可以使用這個 Category。
  • AVAudioSessionCategoryAudioProcessing,只支援本地音頻編解碼處理。不支援播放和錄製。
  • AVAudioSessionCategoryMultiRoute,支援音頻播放和錄製。允許多條音頻流的同步輸入和輸出。(比如USB串連外部擴音器輸出音頻,藍芽耳機同時播放另一路音頻這種特殊需求)

我們也可以通過AVAudioSession的屬性來讀取當前裝置支援的Category

@property(readonly) NSArray<NSString *> *availableCategories;

這樣可以保證裝置相容性。

設定Category的程式碼範例如下

NSError *setCategoryError = nil;BOOL isSuccess = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:&setCategoryError];if (!success) {     //這裡可以讀取setCategoryError.localizedDescription查看錯誤原因}
3. AVAudioSession Mode&&Options

剛剛介紹的Category定義了七種主情境,實際開發需求中有時候需要對Category進行微調整,我們發現這個介面還有兩個參數Mode和Options。

/* set session category and mode with options */- (BOOL)setCategory:(NSString *)category mode:(NSString *)mode options:(AVAudioSessionCategoryOptions)options error:(NSError **)outError API_AVAILABLE(ios(10.0), watchos(3.0), tvos(10.0));
AVAudioSession Mode

我們通過讀取下面這條屬性擷取當前裝置支援的Mode

@property(readonly) NSArray<NSString *> *availableModes;

iOS下有七種mode來定製我們的Category行為

模式 相容的 Category 情境
AVAudioSessionModeDefault All 預設模式
AVAudioSessionModeVoiceChat AVAudioSessionCategoryPlayAndRecord VoIP
AVAudioSessionModeGameChat AVAudioSessionCategoryPlayAndRecord 遊戲錄製,GKVoiceChat自動化佈建
AVAudioSessionModeVideoRecording AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryRecord 錄製視頻
AVAudioSessionModeMoviePlayback AVAudioSessionCategoryPlayback 視頻播放
AVAudioSessionModeMeasurement AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryRecord AVAudioSessionCategoryPlayback 最小系統
AVAudioSessionModeVideoChat AVAudioSessionCategoryPlayAndRecord 視訊通話

下面逐一介紹下每個Mode

  • AVAudioSessionModeDefault,預設模式,與所有的 Category 相容

  • AVAudioSessionModeVoiceChat,適用於VoIP 類型的應用。只能是 AVAudioSessionCategoryPlayAndRecord Category下。在這個模式系統會自動設定AVAudioSessionCategoryOptionAllowBluetooth 這個選項。系統會自動選擇最佳的內建麥克風組合支援語音交談。

  • AVAudioSessionModeVideoChat,用於視訊交談類型應用,只能是 AVAudioSessionCategoryPlayAndRecord Category下。適在這個模式系統會自動設定 AVAudioSessionCategoryOptionAllowBluetooth 和 AVAudioSessionCategoryOptionDefaultToSpeaker 選項。系統會自動選擇最佳的內建麥克風組合可使用視訊聊天。

  • AVAudioSessionModeGameChat,適用於遊戲類應用。使用 GKVoiceChat 對象的應用會自動化佈建這個模式和 AVAudioSessionCategoryPlayAndRecord Category。實際參數和AVAudioSessionModeVideoChat一致

  • AVAudioSessionModeVideoRecording,適用於使用網路攝影機採集視頻的應用。只能是 AVAudioSessionCategoryPlayAndRecord 和 AVAudioSessionCategoryRecord 這兩個 Category下。這個模式搭配 AVCaptureSession API 結合來用可以更好地控制音視頻的輸入輸出路徑。(例如,設定 automaticallyConfiguresApplicationAudioSession 屬性,系統會自動選擇最佳輸出路徑。

  • AVAudioSessionModeMeasurement,最小化系統。只用於 AVAudioSessionCategoryPlayAndRecord、AVAudioSessionCategoryRecord、AVAudioSessionCategoryPlayback 這幾種 Category。

  • AVAudioSessionModeMoviePlayback,適用於播放視頻的應用。只用於 AVAudioSessionCategoryPlayback 這個Category。

AVAudioSession Options

我們還可以使用options去微調Category行為,如下表

Option Option功能說明 相容的 Category
AVAudioSessionCategoryOptionMixWithOthers 支援和其他APP音頻 mix AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryPlayback AVAudioSessionCategoryMultiRoute
AVAudioSessionCategoryOptionDuckOthers 系統智能調低其他APP音頻音量 AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryPlayback AVAudioSessionCategoryMultiRoute
AVAudioSessionCategoryOptionAllowBluetooth 支援藍芽音頻輸入 AVAudioSessionCategoryRecord AVAudioSessionCategoryPlayAndRecord
AVAudioSessionCategoryOptionDefaultToSpeaker 設定預設輸出音頻到擴音器 AVAudioSessionCategoryPlayAndRecord
調優我們的Category

通過Category和合適的Mode和Options的搭配我們可以調優出我們的效果,下面舉兩個應用情境:

用過高德地圖的都知道,在背景播放QQ音樂的時候,如果導航語音出來,QQ音樂不會停止,而是被智能壓低和混音,等導航語音播報完後,QQ音樂正常播放,這裡我們需要後台播放音樂,所以Category使用AVAudioSessionCategoryPlayback,需要混音和智能壓低其他APP音量,所以Options選用 AVAudioSessionCategoryOptionMixWithOthers和AVAudioSessionCategoryOptionDuckOthers

程式碼範例如下

 BOOL isSuccess = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers | AVAudioSessionCategoryOptionDuckOthers error:&setCategoryError];

又或者我希望AVAudioSessionCategoryPlayAndRecord這個Category預設的音頻由擴音器播放,那麼可以調用這個介面去調整Category

- (BOOL)setCategory:(NSString *)category withOptions:(AVAudioSessionCategoryOptions)options error:(NSError **)outError

通過選擇合適和Category,mode和options,就可以調優音訊輸入輸出,來滿足日常開發需求(需要注意的是Category,mode,option是搭配使用的,而不是簡單組合,也就是說某種Category支援某些mode和option,從上面的表中也可以看出這一點)

4. 音頻中斷處理

其他APP或者電話會中斷我們的APP音頻,所以相應的我們要做出處理。
我們可以通過監聽AVAudioSessionInterruptionNotification這個key擷取音頻中斷事件

回調回來Userinfo有索引值

  • AVAudioSessionInterruptionTypeKey:
    取值AVAudioSessionInterruptionTypeBegan表示中斷開始
    取值AVAudioSessionInterruptionTypeEnded表示中斷結束

中斷開始:我們需要做的是儲存好播放狀態,上下文,更新使用者介面等
中斷結束:我們要做的是恢複好狀態和上下文,更新使用者介面,根據需求準備好之後選擇是否啟用我們session。

選擇不同的音頻播放技術,處理中斷方式也有差別,具體如下:

  • System Sound Services:使用 System Sound Services 播發音頻,系統會自動處理,不受APP控制,當中斷髮生時,音頻播放會靜音,當中斷結束後,音頻播放會恢複。

  • AV Foundation framework:AVAudioPlayer 類和 AVAudioRecorder 類提供了中斷開始和結束的 Delegate 回調方法來處理中斷。中斷髮生,系統會自動停止播放,需要做的是記錄播放時間等狀態,更新使用者介面,等中斷結束後,再次調用播放方法,系統會自動啟用session。

  • Audio Queue Services, I/O audio unit:使用aduio unit這些技術需要處理中斷,需要做的是記錄播放或者錄製的位置,中斷結束後自己恢複audio session。

  • OpenAL:使用 OpenAL 播放時,同樣需要自己監聽中斷。管理 OpenAL上下文,使用者中斷結束後恢複audio session。

需要注意的是:1. 有中斷開始事件,不一定對應有中斷結束事件,所以需要在使用者進入前台,點擊UI操作的時候,需要儲存好播放狀態和對Audio Session管理,以便不影響APP的音頻功能。2.音頻資源競爭上,一定是電話優先。3. AVAudioSession同樣可以監聽外設音頻狀態,比如耳機拔入拔出。這裡不做累述

5. AVAudioSession總結

AVAudioSession的作用就是管理音頻這一唯一硬體資源的分配,通過調優合適的AVAudioSession來適配我們的APP對於音訊功能需求。切換音頻情境時候,需要相應的切換AVAudioSession。

參考文獻:Audio Session Programming Guide

from:https://www.jianshu.com/p/fb0e5fb71b3c

【轉】iOS 音頻-AVAudioSession

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.