iOS直播間關閉??

今天微信視頻通話的時候因為有別的人搭話,所以隨手關閉了視頻的??,發(fā)現(xiàn)大家直播過程中會不會也會有這樣的需求,所以看了iOS的api,發(fā)現(xiàn)真的可以,光有視頻,沒有音頻,audio數(shù)據(jù)不會上傳,保護了隱私,還是有一定的應用場景的。廢話到此為止,下面是實現(xiàn)和相關的api。

[[AVAudioSession sharedInstance] 
setCategory:AVAudioSessionCategoryPlayback error:&error];

AVAudioSession Category

AVAudioSession的接口比較簡單。APP啟動的時候會自動幫激活AVAudioSession,當然我們可以手動激活代碼如下。

    //導入頭文件
    #import <AVFoundation/AVFoundation.h>

    //AVAudioSession是一個單例類
    AVAudioSession *session = [AVAudioSession sharedInstance];
    //AVAudioSessionCategorySoloAmbient是系統(tǒng)默認的category
    [session setCategory:AVAudioSessionCategorySoloAmbient error:nil];
    //激活AVAudioSession
    [session setActive:YES error:nil];

可以看到設置session這里有兩個參數(shù),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,這個是系統(tǒng)默認使用的 Category,只支持音頻播放。音頻會被靜音鍵和鎖屏鍵靜音。和AVAudioSessionCategoryAmbient不同的是,這個會打斷其他應用的音頻播放

  • AVAudioSessionCategoryPlayback,只支持音頻播放。你的音頻不會被靜音鍵和鎖屏鍵靜音。適用于音頻是主要功能的APP,像網(wǎng)易云這些音樂app,鎖屏后依然可以播放。

需要注意一下,選擇支持在靜音鍵切到靜音狀態(tài)以及鎖屏鍵切到鎖屏狀態(tài)下仍然可以播放音頻 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定義了七種主場景,實際開發(fā)需求中有時候需要對Category進行微調整,我們發(fā)現(xiàn)這個接口還有兩個參數(shù)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 最小系統(tǒng)
AVAudioSessionModeVideoChat AVAudioSessionCategoryPlayAndRecord 視頻通話

下面逐一介紹下每個Mode

  • AVAudioSessionModeDefault,默認模式,與所有的 Category 兼容

  • AVAudioSessionModeVoiceChat,適用于VoIP 類型的應用。只能是 AVAudioSessionCategoryPlayAndRecord Category下。在這個模式系統(tǒng)會自動配置AVAudioSessionCategoryOptionAllowBluetooth 這個選項。系統(tǒng)會自動選擇最佳的內置麥克風組合支持語音聊天。

  • AVAudioSessionModeVideoChat,用于視頻聊天類型應用,只能是 AVAudioSessionCategoryPlayAndRecord Category下。適在這個模式系統(tǒng)會自動配置 AVAudioSessionCategoryOptionAllowBluetooth 和 AVAudioSessionCategoryOptionDefaultToSpeaker 選項。系統(tǒng)會自動選擇最佳的內置麥克風組合支持視頻聊天。

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

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

  • AVAudioSessionModeMeasurement,最小化系統(tǒng)。只用于 AVAudioSessionCategoryPlayAndRecord、AVAudioSessionCategoryRecord、AVAudioSessionCategoryPlayback 這幾種 Category。

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

AVAudioSession Options

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

Option Option功能說明 兼容的 Category
AVAudioSessionCategoryOptionMixWithOthers 支持和其他APP音頻 mix AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryPlayback AVAudioSessionCategoryMultiRoute
AVAudioSessionCategoryOptionDuckOthers 系統(tǒng)智能調低其他APP音頻音量 AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryPlayback AVAudioSessionCategoryMultiRoute
AVAudioSessionCategoryOptionAllowBluetooth 支持藍牙音頻輸入 AVAudioSessionCategoryRecord AVAudioSessionCategoryPlayAndRecord
AVAudioSessionCategoryOptionDefaultToSpeaker 設置默認輸出音頻到揚聲器 AVAudioSessionCategoryPlayAndRecord

調優(yōu)我們的Category

通過Category和合適的Mode和Options的搭配我們可以調優(yōu)出我們的效果,下面舉兩個應用場景:

用過高德地圖的都知道,在后臺播放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,就可以調優(yōu)音頻的輸入輸出,來滿足日常開發(fā)需求(需要注意的是Category,mode,option是搭配使用的,而不是簡單組合,也就是說某種Category支持某些mode和option,從上面的表中也可以看出這一點)

4. 音頻中斷處理

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

回調回來Userinfo有鍵值

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

中斷開始:我們需要做的是保存好播放狀態(tài),上下文,更新用戶界面等
中斷結束:我們要做的是恢復好狀態(tài)和上下文,更新用戶界面,根據(jù)需求準備好之后選擇是否激活我們session。

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

  • System Sound Services:使用 System Sound Services 播發(fā)音頻,系統(tǒng)會自動處理,不受APP控制,當中斷發(fā)生時,音頻播放會靜音,當中斷結束后,音頻播放會恢復。

  • AV Foundation framework:AVAudioPlayer 類和 AVAudioRecorder 類提供了中斷開始和結束的 Delegate 回調方法來處理中斷。中斷發(fā)生,系統(tǒng)會自動停止播放,需要做的是記錄播放時間等狀態(tài),更新用戶界面,等中斷結束后,再次調用播放方法,系統(tǒng)會自動激活session。

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

  • OpenAL:使用 OpenAL 播放時,同樣需要自己監(jiān)聽中斷。管理 OpenAL上下文,用戶中斷結束后恢復audio session。

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

5. AVAudioSession總結

AVAudioSession的作用就是管理音頻這一唯一硬件資源的分配,通過調優(yōu)合適的AVAudioSession來適配我們的APP對于音頻的功能需求。切換音頻場景時候,需要相應的切換AVAudioSession。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容