IOS音視頻(四十三)AVFoundation 之 Audio Session

IOS音視頻(一)AVFoundation核心類html

IOS音視頻(二)AVFoundation視頻捕捉ios

IOS音視頻(三)AVFoundation 播放和錄音編程

IOS音視頻(四十三)AVFoundation 之 Audio Sessionswift

IOS音視頻(四十四)AVFoundation 之 Audio Queue Services數組

IOS音視頻(四十五)HTTPS 自簽名證書 實現邊下邊播bash

IOS音視頻(四十六)離線在線語音識別方案服務器

1.音頻會話概述

音頻是iOS、tvOS和watchOS中的託管服務。系統經過使用音頻會話來管理應用程序、應用程序間和設備級別上的音頻行爲。session

音頻會話

你使用一個音頻會話來與系統溝通,告訴系統你打算如何在你的應用程序中使用音頻。這個音頻會話充當了你的應用程序和操做系統之間的媒介,反過來,也就是底層音頻硬件之間的媒介。你可使用它來與操做系統交流應用程序音頻的性質,而無需詳細說明具體的行爲或與音頻硬件的必要交互。將這些細節的管理委託給音頻會話能夠確保對用戶音頻體驗的最佳管理。app

你與你的應用程序的音頻會話使用AVAudioSession的一個實例:框架

  1. 配置音頻會話類別和模式,以向系統傳達您打算如何在應用程序中使用音頻
  2. 激活你的應用程序的音頻會話,把你的類別和模式配置到行動
  3. 訂閱和響應重要的音頻會話通知,如音頻中斷和路由更改
  4. 執行高級音頻設備配置,如設置採樣速率、I/O緩衝區持續時間和通道數量
  • 音頻會話管理音頻行爲 音頻會話是應用程序和操做系統之間的中介,用於配置應用程序的音頻行爲。在啓動時,你的應用程序會自動提供一個單例音頻會話。您能夠配置它來提供所需的行爲,並激活它來將該行爲轉化爲操做。

  • 類別表示音頻角色

表達音頻行爲的主要機制是音頻會話類別。經過設置類別,您能夠指示應用程序是否使用輸入或輸出路徑,是否但願音樂與音頻一塊兒繼續播放,等等。你指定的行爲應該知足用戶的指望,正如在iOS人機界面指南音頻中描述的那樣。

AVFoundation定義了許多音頻會話類別,以及一組覆蓋和修改開關,容許您根據應用程序的個性或角色自定義音頻行爲。各類類別支持回放、錄製和帶有錄製的回放。當系統知道您的應用程序的音頻角色時,它將爲您提供對硬件資源的適當訪問。該系統還確保設備上的其餘音頻以適合您的應用程序的方式工做,並符合用戶的指望。

某些類別還能夠經過指定用於專門化給定類別的行爲的模式來進一步定製。例如,當應用程序使用視頻錄製模式時,系統可能會選擇不一樣於使用默認模式時的內置麥克風。該系統還可能採用爲視頻錄製用例進行調優的麥克風信號處理。

  • 通知支持中斷處理 音頻中斷是應用程序的音頻會話的停用,它會當即中止音頻。當來自應用程序的競爭音頻會話被激活,而且該會話未被系統分類以與您的會話混合時,就會出現中斷。您的應用程序應該經過保存狀態、更新用戶界面等方式來響應中斷。要在音頻中斷開始和結束時獲得通知,請註冊以觀察AVAudioSessionInterruptionNotification類型的通知。

  • 通知支持音頻路由更改處理 當用戶經過鏈接或斷開設備、插入或斷開耳機來啓動音頻路由更改時,他們有特定的指望。iOS人機界面指南描述了這些指望,並提供瞭如何知足這些指望的指南。經過註冊來觀察AVAudioSessionRouteChangeNotification類型的通知來處理路由更改。

  • 音頻會話控制設備配置 應用程序不能直接控制設備硬件,但音頻會話爲您提供了請求首選硬件設備設置的接口。這個接口使您可以執行高級音頻設備配置,如設置採樣速率、I/O緩衝區持續時間和音頻通道的數量。

  • 音頻會話保護用戶隱私 單獨或與視頻一塊兒錄製音頻的應用程序,在容許錄製以前,須要明確的用戶許可。在用戶授予你的應用錄製權限以前,應用只能錄製靜音。AVAudioSession提供了請求此權限並肯定用戶隱私設置的接口。

2. 配置音頻會話

音頻會話類別是一個鍵,用於識別應用程序的一組音頻行爲。經過設置一個類別,您能夠向系統代表您的音頻意圖——例如,當鈴聲/靜音開關翻轉時,音頻是否應該繼續。幾個音頻會話類別,以及一組覆蓋和修改開關,讓您自定義您的應用程序的音頻行爲。

如表B-1所示,每一個音頻會話類別都指定了一組特定的響應,以響應下列每一個行爲:

  1. 中斷非混合應用程序音頻:若是是,當你的應用程序激活其音頻會話時,非混合應用程序被中斷。
  2. 靜音開關靜音:若是是,當用戶激活靜音開關時,您的音頻將被靜音。(在iPhone上,這個開關叫作鈴聲/靜音開關。)
  3. 支持音頻輸入:若是支持,則容許app音頻輸入(錄製)。
  4. 支持音頻輸出:若是是,應用程序音頻輸出(播放)是容許的。

大多數應用程序只須要在啓動時設置類別一次,但你能夠根據須要隨時更改類別。你能夠改變它,而音頻會話是積極的;然而,在更改類別或其餘會話屬性以前,一般更可取的作法是禁用音頻會話。在會話被停用時進行這些更改能夠防止音頻系統進行沒必要要的從新配置。

2.1 音頻會話默認行爲

全部的iOS、tvOS和watchOS應用程序都有一個預設的默認音頻會話,以下所示:

  • 支持音頻播放,但不容許錄製音頻。
  • 在iOS系統中,將鈴聲/靜音開關設置爲靜音模式,應用程序播放的任何音頻都會被靜音。
  • 在iOS系統中,當設備被鎖定時,應用程序的音頻會被靜音。
  • 當您的應用程序播放音頻時,任何其餘背景音頻(如音樂應用程序播放的音頻)都將被靜音。

默認的音頻會話具備有用的行爲,但在大多數狀況下,您應該自定義它以更好地知足您的應用程序的須要。要更改行爲,須要配置應用程序的音頻會話。

2.2 配置音頻會話

配置音頻會話的主要方法是設置其類別。音頻會話類別定義了一組音頻行爲。與每一個類別相關的精確行爲並不在應用程序的控制之下,而是由操做系統設置的。蘋果可能會在將來的操做系統版本中完善類別行爲,因此你最好的策略是選擇最準確地描述你想要的音頻行爲意圖的類別。音頻會話類別和模式總結了每一個類別的行爲細節。

雖然類別設置了應用程序的基本音頻行爲,但您能夠經過設置類別的模式進一步專門化這些行爲。例如,IP語音(VoIP)應用程序將使用AVAudioSessionCategoryPlayAndRecord。您能夠經過將音頻會話模式設置爲AVAudioSessionModeVoiceChat來專門化VoIP應用程序的此類行爲。這種模式確保經過系統提供的信號處理來優化語音信號。

AVAudioSessionCategoryPlayAndRecord模式以下:

static let playAndRecord: AVAudioSession.Category
複製代碼
  1. 您的音頻繼續與靜音開關設置爲靜音和與屏幕鎖定。(這個開關在iPhone上被稱爲鈴聲/靜音開關。)爲了在你的應用程序轉換到背景時(例如,當屏幕鎖定時)繼續播放音頻,在你的信息屬性列表文件的UIBackgroundModes鍵中添加音頻值。
  2. 這個類別適用於同時錄製和回放,也適用於錄製和回放但不是同時播放的應用程序。
  3. 默認狀況下,使用這個類別意味着你的應用程序的音頻是不可混合的——激活你的會話將中斷任何其餘不可混合的音頻會話。要容許混合此類別,請使用mixWithOthers選項。
  4. 用戶必須爲音頻錄製授予權限(參見錄製須要用戶權限)。 這個類別支持Airplay的鏡像版本。然而,若是AVAudioSessionModeVoiceChat模式用於此類別,則AirPlay鏡像將被禁用。
  5. 某些類別支持經過在會話上設置一個或多個類別選項來覆蓋其默認行爲(參見AVAudioSessionCategoryOptions)。例如,當會話被激活時,與AVAudioSessionCategoryPlayback類別相關聯的默認行爲會中斷其餘系統音頻。在大多數狀況下,回放應用程序須要這種行爲。可是,若是您但願您的音頻與其餘系統音頻混合,您能夠經過在會話中設置AVAudioSessionCategoryOptionMixWithOthers選項來覆蓋此行爲。
  • 音頻會話模式有:
    音頻會話模式有

注意:當鈴聲/靜音開關設置爲靜音並鎖定屏幕時,爲了讓你的應用程序繼續播放音頻,請確保UIBackgroundModes音頻鍵已添加到你的應用程序的信息中。plist文件。這個要求是除了你使用正確的類別。

  • 模式及相關類別:
    模式及相關類別
    要設置音頻會話類別(以及可選的模式和選項),請調用setCategory:mode:options:error: method,使用AVFoundation框架設置音頻會話類別代碼以下:
// Access the shared, singleton audio session instance
let session = AVAudioSession.sharedInstance()
do {
    // Configure the audio session for movie playback
    try session.setCategory(AVAudioSessionCategoryPlayback,
                            mode: AVAudioSessionModeMoviePlayback,
                            options: [])
} catch let error as NSError {
    print("Failed to set the audio session category and mode: \(error.localizedDescription)")
}

複製代碼

2.3 使用多路由類別擴展選項

多路由類別的工做方式與其餘類別略有不一樣。全部其餘類別的設備都遵循「最後入網」規則,即最後插入輸入或輸出路由的設備是占主導地位的設備。可是,多路由類容許應用程序使用全部鏈接的輸出端口,而不是僅使用最後一個端口。例如,若是您正在經過HDMI輸出路徑聽音頻,並插入一組耳機,您的應用程序將繼續經過HDMI輸出路徑播放音頻,同時也經過耳機播放音頻。

使用multiroute類別,您的應用程序還能夠將不一樣的音頻流發送到不一樣的輸出路徑。例如,您的應用程序能夠將一個音頻流發送到左側耳機,另外一個發送到右側耳機,第三個發送到HDMI路由。圖1-1顯示了將多個音頻流發送到不一樣音頻路由的示例。

發送不一樣的音頻流到不一樣的音頻路由

根據設備和任何鏈接的附件,如下是有效的輸出路徑組合:

  • USB和耳機
  • HDMI和耳機
  • 列隊爭球和耳機

多路由類別支持使用單個輸入端口。

重要提示:只有在沒有其餘合適的輸出端口(USB、HDMI、LineOut)鏈接時才能使用內置揚聲器。

2.4 爲AirPlay選擇類別和模式

只有特定的類別和模式支持AirPlay。如下類別同時支持鏡像和非鏡像版本的AirPlay:

AVAudioSessionCategorySoloAmbient AVAudioSessionCategoryAmbient AVAudioSessionCategoryPlayback

AVAudioSessionCategoryPlayAndRecord類別和如下模式只支持鏡像版本的AirPlay:

AVAudioSessionModeDefault AVAudioSessionModeVideoChat AVAudioSessionModeGameChat

注意:從ios10開始,當你使用AVAudioSessionCategoryPlayAndRecord目錄時,你能夠經過AVAudioSessionCategoryOptionAllowAirPlay選項激活你的會話來啓用非鏡像AirPlay輸出。

AVAudioSessionCategoryOptionAllowAirPlay = 0x40

  1. 只有在音頻會話類別爲AVAudioSessionCategoryPlayAndRecord時,才能顯式設置此選項。對於大多數其餘音頻會話類別,系統將隱式地設置此選項。使用AVAudioSessionCategoryMultiRoute或AVAudioSessionCategoryRecord類別的音頻會話隱式地清除此選項。
  2. 若是您清除此選項,AirPlay設備將不會顯示爲可用的音頻輸出路由。若是設置此選項,這些設備將顯示爲可用的輸出路由。

2.5 開啓後臺音頻

iOS和tvOS應用程序要求您爲某些後臺操做啓用某些功能。回放應用程序須要的一個常見功能是播放背景音頻。啓用這個功能後,當用戶切換到其餘應用程序或鎖定iOS設備時,應用程序的音頻能夠繼續。在iOS中支持高級回放功能,如AirPlay流媒體播放和圖片中的圖片回放,也須要此功能。

配置這些功能的最簡單方法是使用Xcode。在Xcode中選擇應用程序的目標並選擇capability選項卡。在capability選項卡下,將背景模式設置爲ON,並從可用模式列表中選擇「Audio, AirPlay, and Picture in Picture」選項。

開啓後臺音頻模式

啓用此後臺模式,並將音頻會話配置爲適當的類別,您的應用程序就能夠開始播放後臺音頻了

注意:要容許視頻演示的音頻部分在後臺播放,請參閱媒體播放編程指南中的播放背景音頻

3. 激活音頻會話

您已經經過設置音頻會話的類別、選項和模式來配置它。要使配置生效,如今須要激活音頻會話。

3.1 系統如何解決競爭的音頻需求

當你的應用程序啓動時,內置的應用程序(消息、音樂、Safari、手機)可能在後臺運行。每個均可以產生音頻:一條短信來了,你10分鐘前開始的播客還在繼續播放,等等。

若是你把一個設備想象成一個機場,應用程序就像滑行的飛機,這個系統就像一個控制塔。你的應用程序能夠發出音頻請求並聲明它想要的優先級,可是「在停機坪上」發生的事情的最終權威來自系統。使用音頻會話與「控制塔」通訊。圖2-1展現了一個典型的場景—您的應用程序要求在音樂應用程序已經在播放時使用音頻。在這個場景中,您的應用程序中斷了音樂應用程序。

系統如何解決競爭的音頻需求

在圖的第1步中,應用程序請求激活它的音頻會話。例如,在應用程序啓動時,或者在用戶輕擊音頻錄製和回放應用程序中的Play按鈕時,您可能會發出這樣的請求。在步驟2中,系統將考慮激活請求。具體來講,它會考慮您分配給音頻會話的類別。在圖2-1中,您的應用程序使用了一個類別,該類別須要對其餘音頻進行消音。

在步驟3和步驟4中,系統關閉音樂應用程序的音頻會話,中止其音頻播放。最後,在第五步,系統激活你的應用程序的音頻會話和播放能夠開始。

3.2 激活和關閉您的音頻會話

雖然AVFoundation回放和錄製類會自動激活音頻會話,但手動激活它會讓您有機會測試激活是否成功。可是,若是你的應用程序有一個play/pause UI元素,那麼編寫你的代碼,這樣用戶必須在激活會話以前按play。一樣,在更改音頻會話的活動/非活動狀態時,請檢查以確保調用成功。編寫代碼來優雅地處理系統拒絕激活您的會話。

該系統將關閉您的音頻會話,用於時鐘或日曆鬧鐘或來電。當用戶解除警報或選擇忽略電話呼叫時,系統容許您的會話再次激活。是否在中斷結束時從新激活會話取決於應用程序類型,如Audio Guidelines By app type所述。

  • 激活音頻會話的代碼以下:
let session = AVAudioSession.sharedInstance()
do {
    // 1) Configure your audio session category, options, and mode
    // 2) Activate your audio session to enable your custom configuration
    try session.setActive(true)
} catch let error as NSError {
    print("Unable to activate audio session: \(error.localizedDescription)")
}
複製代碼

若要停用音頻會話,請將false傳遞給setActive方法。

當使用AVFoundation對象(AVPlayer、AVAudioRecorder等)播放或錄製音頻時,系統負責在中斷結束時從新激活音頻會話。可是,若是您註冊了通知消息並顯式地從新激活音頻會話,則能夠驗證從新激活成功,並能夠更新應用程序的狀態和用戶界面。有關更多信息,請參見圖3-1。

許多應用程序歷來不須要顯式地停用它們的音頻會話。重要的例外包括VoIP應用程序、逐嚮導航應用程序,在某些狀況下還包括回放和錄音應用程序。

  • 確保VoIP應用程序的音頻會話(一般在後臺運行)僅在應用程序處理調用時是活動的。在後臺,準備接收電話時,VoIP應用程序的音頻會話不該處於激活狀態。
  • 確保使用錄製類別的應用程序的音頻會話僅在錄製時處於活動狀態。在開始錄製和中止錄製以前,請確保您的會話處於非活動狀態,以容許播放其餘聲音,例如傳入消息警報。
  • 若是應用程序支持後臺音頻播放或錄製,若是應用程序不積極使用音頻(或準備使用音頻),則在進入後臺時禁用其音頻會話。這樣作容許系統釋放音頻資源,以便其餘進程可使用它們。它還能夠防止應用程序的音頻會話在應用程序進程被操做系統掛起時失效(參見AVAudioSessionInterruptionWasSuspendedKey)。

這個userInfo鍵只出如今AVAudioSession.InterruptionType中。開始中斷事件,其中中斷是操做系統掛起應用程序的直接結果。它的關聯值是一個布爾NSNumber,其中一個真值表示中斷是因爲系統掛起應用程序形成的,而不是由另外一個音頻會話中斷的。

3.2.1 Audio Guidelines By app type

3.3 檢查其餘音頻是否正在播放

當你的應用程序激活時,聲音可能已經在設備上播放了。例如,當用戶啓動應用程序時,音樂應用程序可能正在播放歌曲,或者Safari可能正在播放音頻流。若是你的應用是一款遊戲,瞭解是否有其餘音頻在播放尤爲重要。許多遊戲都有音樂音軌和音效。在iOS人機界面指南中,建議你假設用戶在玩遊戲時但願其餘音頻和遊戲音效可以繼續。

在你的應用委派的applicationDidBecomeActive:方法中,檢查音頻會話的secondaryAudioShouldBeSilencedHint屬性,以肯定音頻是否已經在播放。當另外一個具備非混合音頻會話的應用程序正在播放音頻時,該值爲true。應用程序應該使用這個屬性做爲使次要於應用程序功能的音頻靜音的提示。例如,一個使用AVAudioSessionCategoryAmbient的遊戲可使用這個屬性來決定是否應該在保持聲音效果不靜音的狀況下靜音音軌。

您還能夠訂閱類型爲AVAudioSessionSilenceSecondaryAudioHintNotification的通知,以確保在可選的輔助音頻靜音應該開始或結束時通知您的應用程序。此通知僅發送給當前處於前臺且具備活動音頻會話的已註冊偵聽器。

func setupNotifications() {
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(handleSecondaryAudio),
                                           name: .AVAudioSessionSilenceSecondaryAudioHint,
                                           object: AVAudioSession.sharedInstance())
}
 
func handleSecondaryAudio(notification: Notification) {
    // Determine hint type
    guard let userInfo = notification.userInfo,
        let typeValue = userInfo[AVAudioSessionSilenceSecondaryAudioHintTypeKey] as? UInt,
        let type = AVAudioSessionSilenceSecondaryAudioHintType(rawValue: typeValue) else {
            return
    }
 
    if type == .begin {
        // Other app audio started playing - mute secondary audio
    } else {
        // Other app audio stopped playing - restart secondary audio
    }
}
複製代碼

此通知的userInfo字典包含AVAudioSessionSilenceSecondaryAudioHintType值的AVAudioSessionSilenceSecondaryAudioHintTypeKey。使用音頻提示類型來肯定輔助音頻靜音應該開始仍是結束

4. 響應中斷

添加音頻會話代碼來處理中斷,確保您的應用程序的音頻在電話到來、時鐘或日曆鬧鈴響或其餘應用程序激活其音頻會話時繼續正常工做。

音頻中斷是應用程序的音頻會話的停用,它會當即中止音頻。當來自應用程序的競爭音頻會話被激活,而且該會話沒有被系統分類以與您的會話混合時,就會發生中斷。在您的會話變爲非活動狀態後,系統將發送一條「您被中斷了」消息,您能夠經過保存狀態、更新用戶界面等方式對其進行響應。

您的應用程序可能會在中斷後暫停。當用戶接電話時就會發生這種狀況。若是用戶忽略了一個呼叫,或者取消了一個警報,系統就會發出一個「中斷結束」的消息,你的應用程序就會繼續運行。要恢復您的音頻,您必須從新激活您的音頻會話。

4.1 中斷生命週期

圖3-1說明了播放應用程序的音頻會話中斷以前、期間和以後的事件序列。

中斷生命週期

中斷事件—在本例中,FaceTime請求的到來—按以下方式進行。編號的步驟與圖中的數字相對應。

  1. 你的應用程序是活動的,播放音頻。
  2. FaceTime請求到達。系統激活FaceTime應用程序的音頻會話。
  3. 系統將關閉您的音頻會話。此時,應用程序中的回放已經中止。
  4. 系統會發出一個通知,指示您的會話已被停用。
  5. 您的通知處理程序將採起適當的操做。例如,它能夠更新用戶界面並保存在中止回放時恢復回放所需的信息。
  6. 若是用戶拒絕中斷(忽略傳入的FaceTime請求),系統就會發出通知,代表中斷已經結束。
  7. 通知處理程序在中斷結束時採起適當的操做。例如,它能夠更新用戶界面、從新激活音頻會話和恢復播放。
  8. (圖中未顯示)若是用戶接了一個電話,而不是在第6步取消中斷,你的應用程序將被掛起。

4.2 音頻中斷處理技術

經過註冊觀察AVAudioSession發佈的中斷通知來處理中斷。您在中斷代碼中所作的事情取決於您正在使用的音頻技術,以及您在回放、錄製、音頻格式轉換、讀取流音頻包等方面所使用的技術。通常來講,從用戶的角度來看,您須要確保儘量少的中斷和儘量好的恢復。

表3-1總結了中斷期間適當的音頻會話行爲。若是您使用AVFoundation回放或錄製對象,系統會自動處理其中的一些步驟。

表3-1音頻會話中斷期間應該發生什麼:

時間 處理
中斷開始後 1.保存狀態和上下文,2.更新的用戶界面
中斷結束後 1.恢復狀態和上下文,2.更新的用戶界面,3.從新激活音頻會話,若是適當的應用程序

表3-2總結了如何根據技術處理音頻中斷:

音頻技術 中斷處理
1. AVFoundation framework 系統自動暫停播放或錄製中斷和從新激活您的音頻會話時,您恢復播放或錄製。2.若是你想保存和恢復播放位置之間的應用程序啓動,保存播放位置在中斷以及在應用程序退出。
Audio Queue Services, I/O audio unit 這些技術讓你的應用程序控制處理中斷。你負責保存回放或錄製位置,並在中斷結束後從新激活音頻會話。
System Sound Services 當中斷開始時,使用系統聲音服務播放的聲音將變爲靜音。若是中斷結束,聲音能夠再次播放。應用程序不能影響使用這種回放技術的聲音的中斷行爲。

4.3 處理Siri中斷

  • 當Siri打斷你的應用程序回放時,你必須在音頻會話處於中斷狀態時跟蹤Siri發出的任何遠程控制命令。在中斷期間,跟蹤Siri發出的全部命令,並在中斷結束時作出相應的響應。例如,在中斷期間,用戶要求Siri暫停應用程序的音頻播放。當你的應用程序被通知中斷已經結束,它不該該自動恢復播放。相反,應用程序的UI應該指示應用程序處於暫停狀態。

4.4 觀察音頻中斷

  • 要處理音頻中斷,首先註冊AVAudioSessionInterruptionNotification類型的通知。
func registerForNotifications() {
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(handleInterruption),
                                           name: .AVAudioSessionInterruption,
                                           object: AVAudioSession.sharedInstance())
}
 
func handleInterruption(_ notification: Notification) {
    // Handle interruption
}

複製代碼
  • 發佈的NSNotification實例包含一個已填充的userInfo字典,提供中斷的詳細信息。經過從userInfo字典中檢索AVAudioSessionInterruptionType值來肯定中斷的類型。中斷類型指示中斷是已經開始仍是已經結束。
func handleInterruption(_ notification: Notification) {
    guard let info = notification.userInfo,
        let typeValue = info[AVAudioSessionInterruptionTypeKey] as? UInt,
        let type = AVAudioSessionInterruptionType(rawValue: typeValue) else {
            return
    }
    if type == .began {
        // Interruption began, take appropriate actions (save state, update user interface)
    }
    else if type == .ended {
        guard let optionsValue =
            userInfo[AVAudioSessionInterruptionOptionKey] as? UInt else {
                return
        }
        let options = AVAudioSessionInterruptionOptions(rawValue: optionsValue)
        if options.contains(.shouldResume) {
            // Interruption Ended - playback should resume
        }
    }
}
複製代碼
  • 若是中斷類型是AVAudioSessionInterruptionTypeEnded,則userInfo字典可能包含AVAudioSessionInterruptionOptions值。AVAudioSessionInterruptionOptionShouldResume的一個選項值是一個提示,指示若是應用程序在被中斷時正在播放,它是否應該自動恢復播放。媒體播放應用程序在中斷後開始播放以前應始終尋找此標誌。若是它不存在,播放不該該再次開始,直到由用戶發起。沒有播放界面的應用程序,好比遊戲,能夠忽略這個標誌,在中斷結束時從新激活並恢復播放。

注意:不能保證開始中斷會有相應的結束中斷。你的應用程序須要知道一個切換到前臺運行狀態或用戶按下播放按鈕。在這兩種狀況下,肯定你的應用程序是否應該從新激活它的音頻會話。

4.5 響應媒體服務器重置

媒體服務器經過共享服務器進程提供音頻和其餘多媒體功能。雖然不多見,可是媒體服務器能夠在您的應用程序處於活動狀態時進行重置。註冊AVAudioSessionMediaServicesWereResetNotification通知以監視媒體服務器重置。收到通知後,您的app須要作如下工做:

  • 處理孤立的音頻對象(如播放器、錄音機、轉換器或音頻隊列)並建立新對象
  • 重置任何被跟蹤的內部音頻狀態,包括AVAudioSession的全部屬性
  • 在適當的時候,使用setActive:error:方法從新激活AVAudioSession實例

5. 響應路由更改

當您的應用程序運行時,用戶可能會插入或拔出耳機,或使用帶有音頻鏈接的塢站。iOS人機界面指南描述了應用程序應該如何應對此類事件。要實現這些建議,請編寫音頻會話代碼來處理音頻硬件路由更改。某些類型的應用程序,好比遊戲,並不老是須要對路線變化作出響應。然而,其餘類型的應用程序,如媒體播放器,必須響應全部的路由變化。

5.1 各類音頻硬件路由變化

音頻硬件路由是音頻信號的有線電子路徑。當設備的用戶插入或拔出耳機時,系統會自動改變音頻硬件路線。若是你註冊了AVAudioSessionRouteChangeNotification類型的通知,你的應用程序能夠被通知這些變化。

圖4-1描述了在錄製和回放期間各類路由更改的事件序列。圖的底部顯示了四個可能的結果,它們來自您編寫的屬性偵聽器回調函數所採起的操做。

處理硬件線路變換

如圖所示,在您的app啓動後,系統最初會肯定音頻路由。它將在應用程序運行時繼續監視活動路由。首先考慮用戶點擊應用程序中的記錄按鈕的狀況,該按鈕由圖左側的「開始記錄」框表示。

在錄製過程當中,用戶能夠將耳機插入或拔出,如圖左下方所示爲鑽石形狀的決策元件。做爲響應,系統發送一個路由更改通知,其中包含更改的緣由和前一個路由。你的應用程序應該中止錄製。

回放的狀況相似,但結果不一樣,如圖右側所示。若是用戶在播放過程當中拔下耳機,應用程序應該暫停音頻。若是用戶在回放過程當中插入耳機,應用程序應該容許回放繼續。

5.2 觀察音頻路由的變化

  • 發生音頻路由更改的緣由有不少,包括用戶插入一對耳機、鏈接藍牙LE耳機或拔掉USB音頻接口。知道何時發生這些變化可能對你的應用程序很重要,這樣你就能夠更新它的用戶界面或改變它的內部狀態。經過註冊AVAudioSessionRouteChangeNotification類型的通知,能夠在音頻路由更改時通知您。
func setupNotifications() {
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(handleRouteChange),
                                           name: .AVAudioSessionRouteChange,
                                           object: AVAudioSession.sharedInstance())
}
 
func handleRouteChange(_ notification: Notification) {
 
}
複製代碼
  • 發佈的通知包含一個已填充的userInfo字典,提供路由更改的詳細信息。您能夠經過從userInfo字典中檢索AVAudioSessionRouteChangeReason值來肯定這種變化的緣由。當鏈接一個新設備時,緣由是AVAudioSessionRouteChangeReasonNewDeviceAvailable,當一個設備被刪除時,緣由是avaudiosessionroutechangereasonolddeviceavailable。
func handleRouteChange(_ notification: Notification) {
    guard let userInfo = notification.userInfo,
        let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt,
        let reason = AVAudioSessionRouteChangeReason(rawValue:reasonValue) else {
            return
    }
    switch reason {
    case .newDeviceAvailable:
        // Handle new device available.
    case .oldDeviceUnavailable:
        // Handle old device removed.
    default: ()
    }
}
複製代碼
  • 當新設備可用時,您能夠查詢音頻會話的currentRoute屬性,以肯定音頻輸出當前路由到何處。這將返回一個AVAudioSessionRouteDescription對象,該對象列出了音頻會話的全部輸入和輸出。當設備被移除時,您能夠從userInfo字典中檢索上一條路由的AVAudioSessionRouteDescription對象。在這兩種狀況下,您能夠查詢路由描述的輸出屬性,該屬性返回一個AVAudioSessionPortDescription對象數組,提供音頻輸出路由的詳細信息。
func handleRouteChange(notification: NSNotification) {
    guard let userInfo = notification.userInfo,
        let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt,
        let reason = AVAudioSessionRouteChangeReason(rawValue:reasonValue) else {
            return
    }
    switch reason {
    case .newDeviceAvailable:
        let session = AVAudioSession.sharedInstance()
        for output in session.currentRoute.outputs where output.portType == AVAudioSessionPortHeadphones {
            headphonesConnected = true
        }
    case .oldDeviceUnavailable:
        if let previousRoute =
            userInfo[AVAudioSessionRouteChangePreviousRouteKey] as? AVAudioSessionRouteDescription {
            for output in previousRoute.outputs where output.portType == AVAudioSessionPortHeadphones {
                headphonesConnected = false
            }
        }
    default: ()
    }
}
複製代碼

重要提示:媒體播放應用程序應該暫停播放,若是路線改變的緣由是AVAudioSessionRouteChangeReasonOldDeviceUnavailable,但不該該,若是緣由是AVAudioSessionRouteChangeReasonOverride。

注意:音頻路由的更改也可能致使音頻會話的採樣率、I/O緩衝區持續時間、通道計數或其餘硬件相關值的更改。若是這些值對您的應用程序很重要,請在路由更改後查詢它們,以查看它們的值是否已更改。

6. 配置設備硬件

使用音頻會話屬性,您能夠在運行時爲設備硬件優化應用程序的音頻行爲。這樣作可使您的代碼適應它所運行的設備的特性,以及用戶在應用程序運行時所作的更改(如插入耳機或將設備停靠在其上)。

使用AVAudioSession:

  • 爲示例速率和I/O緩衝區持續時間指定首選硬件設置
  • 查詢許多硬件特性,如輸入和輸出延遲、輸入和輸出通道計數、硬件採樣率、硬件卷設置和音頻輸入的可用性

6.1 選擇首選音頻硬件值

使用音頻會話指定您的首選設備設置,如採樣率和硬件I/O緩衝區持續時間。表5-1描述了這些偏好的好處和代價。

選擇硬件
例如,若是音頻質量在您的應用程序中很是重要,而且大文件或緩衝區大小不是一個重要問題,那麼您能夠指定一個高採樣率的首選項。

注意:默認的音頻I/O緩衝時間(44.1 kHz音頻大約0.02秒)爲大多數應用程序提供了足夠的響應能力。您能夠爲延遲關鍵型應用程序(如live musical instrument monitoring)設置一個較低的I/O持續時間,可是對於大多數應用程序,您永遠不須要修改這個設置。

6.2 設置首選音頻硬件值

在激活音頻會話以前設置首選硬件值。若是你已經在運行一個音頻會話,那麼就停用它。對首選值的更改將在音頻會話激活後生效,您能夠在此時驗證更改。清單5-1展現瞭如何設置首選硬件值以及如何驗證它們。

  • 清單5-1設置和驗證音頻硬件值
let session = AVAudioSession.sharedInstance()
 
// Configure category and mode
do {
    try session.setCategory(AVAudioSessionCategoryRecord, mode: AVAudioSessionModeDefault)
} catch let error as NSError {
    print("Unable to set category: \(error.localizedDescription)")
}
 
// Set preferred sample rate
do {
    try session.setPreferredSampleRate(44_100)
} catch let error as NSError {
    print("Unable to set preferred sample rate: \(error.localizedDescription)")
}
 
// Set preferred I/O buffer duration
do {
    try session.setPreferredIOBufferDuration(0.005)
} catch let error as NSError {
    print("Unable to set preferred I/O buffer duration: \(error.localizedDescription)")
}
 
// Activate the audio session
do {
    try session.setActive(true)
} catch let error as NSError {
    print("Unable to activate session. \(error.localizedDescription)")
}
 
// Query the audio session's ioBufferDuration and sampleRate properties
// to determine if the preferred values were set
print("Audio Session ioBufferDuration: \(session.ioBufferDuration), sampleRate: \(session.sampleRate)")
複製代碼

注意:當競爭音頻會話設置首選硬件值時,系統優先考慮非混合會話。使用AVAudioSessionCategoryAmbient類別或AVAudioSessionCategoryOptionMixWithOthers選項的音頻會話不太可能提供其首選的硬件設置。

6.3 選擇和配置麥克風

在擁有兩個或更多內置麥克風的設備上,iOS會經過音頻會話模式自動選擇麥克風。模式指定用於輸入的數字信號處理(DSP)和可能的路由。爲每種模式的用例優化輸入和路由。設置模式還可能影響正在使用的路由的其餘方面。

開發人員還能夠手動選擇麥克風,若是硬件支持,甚至能夠選擇首選的麥克風極性模式。

重要提示:在使用任何輸入選擇功能以前,爲您的應用程序設置音頻會話類別和模式,而後激活音頻會話。

  • 設置首選輸入

要發現內置的或鏈接的輸入端口,請使用音頻會話的availableInputs屬性。此屬性返回AVAudioSessionPortDescription對象數組,這些對象描述設備的可用輸入端口。端口能夠經過它們的portType屬性來標識。要設置首選輸入端口(內置麥克風、有線麥克風、USB輸入,等等),請使用音頻會話的setPreferredInput:error:方法。

  • 設置首選數據源
  1. 一些端口,如內置麥克風和一些USB配件,支持數據源。應用程序能夠經過查詢端口描述的dataSources屬性來發現可用的數據源。對於內置麥克風,返回的數據源描述對象表示每一個麥克風。不一樣的設備爲內置麥克風返回不一樣的值。例如,iPhone 4和iPhone 4S有兩個麥克風:底部和頂部。iPhone 5有三個麥克風:底部、前面和後面。
  2. 單個內置麥克風能夠經過數據源描述的位置屬性(上、下)和方向屬性(前、後等)的組合進行標識。應用程序可使用AVAudioSessionPortDescription對象的setPreferredDataSource:error:方法設置首選數據源。
  • 設置一個首選的極座標模式

一些iOS設備支持爲一些內置麥克風配置麥克風極性模式。麥克風的極模式決定了它對聲音的敏感度與聲源的方向有關。當前的iphone支持爲先後內置麥克風設置首選的極座標模式。可用模式使用數據源描述對象的supportedPolarPatterns屬性返回。此屬性爲數據源返回一個受支持的極性模式數組(如cardioid或omnidirectional),若是沒有可用的可選模式,則返回nil。若是數據源有許多受支持的極性模式,您能夠經過使用數據源描述的setPreferredPolarPattern:error:方法來設置首選的極性模式。

  • 下面的代碼提供了一個簡單的示例,演示如何選擇特定的麥克風並設置其極性模式。
// Preferred Mic = Front, Preferred Polar Pattern = Cardioid
let preferredMicOrientation = AVAudioSessionOrientationFront
let preferredPolarPattern = AVAudioSessionPolarPatternCardioid
 
// Retrieve your configured and activated audio session
let session = AVAudioSession.sharedInstance()
 
// Get available inputs
guard let inputs = session.availableInputs else { return }
 
// Find built-in mic
guard let builtInMic = inputs.first(where: {
    $0.portType == AVAudioSessionPortBuiltInMic
}) else { return }
 
// Find the data source at the specified orientation
guard let dataSource = builtInMic.dataSources?.first (where: {
    $0.orientation == preferredMicOrientation
}) else { return }
 
// Set data source's polar pattern
do {
    try dataSource.setPreferredPolarPattern(preferredPolarPattern)
} catch let error as NSError {
    print("Unable to preferred polar pattern: \(error.localizedDescription)")
}
 
// Set the data source as the input's preferred data source
do {
    try builtInMic.setPreferredDataSource(dataSource)
} catch let error as NSError {
    print("Unable to preferred dataSource: \(error.localizedDescription)")
}
 
// Set the built-in mic as the preferred input
// This call will be a no-op if already selected
do {
    try session.setPreferredInput(builtInMic)
} catch let error as NSError {
    print("Unable to preferred input: \(error.localizedDescription)")
}
 
// Print Active Configuration
session.currentRoute.inputs.forEach { portDesc in
    print("Port: \(portDesc.portType)")
    if let ds = portDesc.selectedDataSource {
        print("Name: \(ds.dataSourceName)")
        print("Polar Pattern: \(ds.selectedPolarPattern ?? "[none]")")
    }
}
複製代碼

在iPhone 6s上運行這段代碼會產生如下控制檯輸出:

Port: MicrophoneBuiltIn
Name: Front
Polar Pattern: Cardioid

複製代碼

6.4 在模擬器中運行應用程序

當你添加音頻會話支持到你的應用程序時,你能夠在模擬器或設備上運行你的應用程序。可是,模擬器不能模擬不一樣進程或音頻路由更改中的音頻會話之間的大多數交互。當運行你的應用程序在模擬器,你不能:

  • 調用一箇中斷
  • 模擬插入或拔出耳機
  • 改變靜音開關的設置
  • 模擬屏幕鎖
  • 測試音頻混合行爲——即將音頻與來自另外一個應用程序(如音樂應用程序)的音頻一塊兒播放。

因爲模擬器的特性,您可能但願對代碼進行條件設置,以容許在模擬器中進行部分測試。下面代碼展現瞭如何作到這一點。

#if arch(i386) || arch(x86_64)
    // Execute subset of code that works in the Simulator
#else
    // Execute device-only code as well as the other code
#endif
複製代碼

7. 保護用戶隱私

爲了保護用戶隱私,你的應用程序在錄製音頻以前必須得到用戶的許可。若是用戶不授予權限,則只記錄靜默。當你使用一個支持記錄的類別,而應用程序試圖使用輸入路徑時,系統會自動提示用戶容許。

您可使用requestRecordPermission:方法來手動請求權限,而不是等待系統提示用戶記錄權限。使用這種方法容許您的應用程序在不中斷應用程序的天然流的狀況下得到許可,從而得到更好的用戶體驗。

AVAudioSession.sharedInstance().requestRecordPermission { granted in
    if granted {
        // User granted access. Present recording interface.
    } else {
        // Present message to user indicating that recording
        // can't be performed until they change their preference
        // under Settings -> Privacy -> Microphone
    }
}
複製代碼

重要提示:從iOS 10開始,全部訪問設備麥克風的應用程序必須靜態地聲明它們的意圖。要作到這一點,應用程序如今必須在它們的信息中包含NSMicrophoneUsageDescription鍵。併爲此鍵提供一個目的字符串。當系統提示用戶容許訪問時,此字符串將做爲警報的一部分顯示。 若是一個應用程序試圖訪問設備的麥克風沒有這個鍵和值存在,應用程序將終止。

8. AVAudioSession

AVAudioSession是一個對象,它向系統傳達你打算如何在你的應用程序中使用音頻。它的類聲明以下:

class AVAudioSession : NSObject 複製代碼

音頻會話充當應用程序和操做系統之間的中介,進而充當底層音頻硬件之間的中介。您使用一個音頻會話來與操做系統通訊應用程序音頻的通常性質,而不詳細說明特定的行爲或與音頻硬件所需的交互。您將這些細節的管理委託給音頻會話,以確保操做系統可以最好地管理用戶的音頻體驗。

全部的iOS、tvOS和watchOS應用程序都有一個默認的音頻會話,並預先配置瞭如下行爲:

  • 它支持音頻回放,但不容許音頻錄製(tvOS不支持音頻錄製)。
  • 在iOS系統中,將鈴聲/靜音開關設置爲靜音模式,應用程序播放的任何音頻都會被靜音。
  • 在iOS系統中,鎖定設備會使應用程序的音頻靜音。
  • 當應用程序播放音頻時,它會靜音任何其餘背景音頻。

雖然默認的音頻會話提供了有用的行爲,但它一般不提供媒體應用程序須要的音頻行爲。要更改默認行爲,須要配置應用程序的音頻會話類別。

你可使用七種可能的類別(參見音頻會話類別和模式),可是回放是回放應用程序最經常使用的一種。這個類別代表音頻播放是你的應用程序的核心功能。當你指定這個類別時,你的應用程序的音頻將繼續與鈴聲/靜音開關設置爲靜音模式(只有iOS)。使用這個類別,你也能夠播放背景音頻,若是你在圖片背景模式中使用音頻,AirPlay和圖片。有關更多信息,請參見啓用背景音頻。

使用AVAudioSession對象來配置應用程序的音頻會話。該類是一個單例對象,用於設置音頻會話的類別、模式和其餘配置。您能夠在應用程序的整個生命週期中與音頻會話進行交互,可是在應用程序啓動時執行此配置一般頗有用,以下面的示例所示。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    
    // Get the singleton instance.
    let audioSession = AVAudioSession.sharedInstance()
    do {
        // Set the audio session category, mode, and options.
        try audioSession.setCategory(.playback, mode: .moviePlayback, options: [])
    } catch {
        print("Failed to set audio session category.")
    }
    
    // Other post-launch configuration.
    return true
}
複製代碼

當您使用setActive(:)或setActive(:options:)方法激活會話時,音頻會話將使用此配置。

請注意 你能夠在設置類別後的任什麼時候候激活音頻會話,但一般最好將此調用推遲到應用程序開始音頻播放以後。延遲調用能夠確保您不會過早地中斷正在進行的任何其餘背景音頻。

8.1 獲取音頻會話

class func sharedInstance() -> AVAudioSession //Returns the shared audio session instance. 複製代碼

8.2 配置音頻會話

var category: AVAudioSession.Category
//The current audio session category.
func setCategory(AVAudioSession.Category)
//Sets the audio session’s category.
var availableCategories: [AVAudioSession.Category]
//The audio session categories available on the current device.
struct AVAudioSession.Category //Audio session category identifiers. var categoryOptions: AVAudioSession.CategoryOptions //The set of options associated with the current audio session category. func setCategory(AVAudioSession.Category, options: AVAudioSession.CategoryOptions) //Sets the audio sessions category with the specified options. struct AVAudioSession.CategoryOptions //Constants that specify optional audio behaviors. var mode: AVAudioSession.Mode //The current audio sessions mode. func setMode(AVAudioSession.Mode) //Sets the audio sessions mode. func setCategory(AVAudioSession.Category, mode: AVAudioSession.Mode, options: AVAudioSession.CategoryOptions) //Sets the audio sessions category, mode, and options. var availableModes: [AVAudioSession.Mode] //The audio session modes available on the device. struct AVAudioSession.Mode //Audio session mode identifiers. var routeSharingPolicy: AVAudioSession.RouteSharingPolicy //The current route-sharing policy. func setCategory(AVAudioSession.Category, mode: AVAudioSession.Mode, policy: AVAudioSession.RouteSharingPolicy, options: AVAudioSession.CategoryOptions) //Sets the session category, mode, route-sharing policy, and options. enum AVAudioSession.RouteSharingPolicy //Cases that indicate the possible route-sharing policies for an audio session. 複製代碼

8.3 激活音頻會話

//使用指定的選項激活或關閉應用程序的音頻會話。
func setActive(Bool, options: AVAudioSession.SetActiveOptions)

//在watchOS上異步激活音頻會話。
func activate(options: AVAudioSessionActivationOptions, completionHandler: (Bool, Error?) -> Void)

複製代碼

8.4 請求錄音權限

//當前的錄音許可狀態。
var recordPermission: AVAudioSession.RecordPermission

//請求用戶錄製音頻的權限。
func requestRecordPermission(PermissionBlock)

複製代碼

8.5 與其餘音頻混合

var isOtherAudioPlaying: Bool
//A Boolean value that indicates whether another app is playing audio.
var secondaryAudioShouldBeSilencedHint: Bool
//A Boolean value that indicates whether another app, with a nonmixable audio session, is playing audio.
var allowHapticsAndSystemSoundsDuringRecording: Bool
//A Boolean value that indicates whether system sounds and haptics play while recording from audio input.
func setAllowHapticsAndSystemSoundsDuringRecording(Bool)
//Sets a Boolean value that indicates whether system sounds and haptics play while recording from audio input.
var promptStyle: AVAudioSession.PromptStyle
//A hint to audio sessions that use voice prompt mode to alter the type of prompts they issue in response to other system audio, such as Siri and phone calls.
enum AVAudioSession.PromptStyle //Constants that indicate the prompt style to use. 複製代碼

8.6 響應音頻會話通知

class let interruptionNotification: NSNotification.Name //A notification thats posted when an audio interruption occurs. class let routeChangeNotification: NSNotification.Name //A notification thats posted when the systems audio route changes. class let silenceSecondaryAudioHintNotification: NSNotification.Name //A notification thats posted when the primary audio from other applications starts and stops. class let mediaServicesWereLostNotification: NSNotification.Name //A notification thats posted when the system terminates the media server. class let mediaServicesWereResetNotification: NSNotification.Name //A notification thats posted when the media server restarts. 複製代碼

8.7 使用音頻路由

//當前音頻路由的輸入和輸出端口的描述。
var currentRoute: AVAudioSessionRouteDescription

//一個對象,它描述與會話的音頻路由相關聯的輸入和輸出端口。
class AVAudioSessionRouteDescription //一個布爾值,指示音頻輸入路徑是否可用。 var isInputAvailable: Bool //一個可用於音頻路由的輸入端口數組。 var availableInputs: [AVAudioSessionPortDescription]? //音頻路由的首選輸入端口。 var preferredInput: AVAudioSessionPortDescription? //設置音頻路由的首選輸入端口。 func setPreferredInput(AVAudioSessionPortDescription?) //關於端口功能及其支持的硬件通道的信息。 class AVAudioSessionPortDescription //當前選擇的輸入數據源。 var inputDataSource: AVAudioSessionDataSourceDescription? //音頻會話當前輸入端口的可用數據源數組。 var inputDataSources: [AVAudioSessionDataSourceDescription]? //選擇音頻會話當前輸入端口的數據源。 func setInputDataSource(AVAudioSessionDataSourceDescription?) //當前音頻路由的可用輸出數據源的數組。 var outputDataSources: [AVAudioSessionDataSourceDescription]? //當前選擇的輸出數據源。 var outputDataSource: AVAudioSessionDataSourceDescription? //設置音頻會話的輸出數據源。 func setOutputDataSource(AVAudioSessionDataSourceDescription?) //爲音頻輸入或輸出定義數據源的對象,提供數據源的名稱、位置和方向等信息。 class AVAudioSessionDataSourceDescription //臨時改變當前的音頻路由。 func overrideOutputAudioPort(AVAudioSession.PortOverride) 複製代碼

8.8 使用音頻通道

//當前路由的音頻輸入通道的數量。
var inputNumberOfChannels: Int

//當前音頻路由可用的最大輸入通道數。
var maximumInputNumberOfChannels: Int

//當前路由的優先輸入通道數。
var preferredInputNumberOfChannels: Int

//設置當前路由的優先輸入通道數。
func setPreferredInputNumberOfChannels(Int)

//音頻輸出通道的數目。
var outputNumberOfChannels: Int

//當前音頻路由可用的最大輸出通道數。
var maximumOutputNumberOfChannels: Int

//當前路由的輸出通道的優先數量。
var preferredOutputNumberOfChannels: Int

//設置當前路由的輸出通道的首選數目。
func setPreferredOutputNumberOfChannels(Int)

複製代碼

8.9 處理音頻設備設置

//應用於與會話相關的輸入的增益。
var inputGain: Float

//一個布爾值,指示是否能夠設置輸入增益。
var isInputGainSettable: Bool

//將輸入增益更改成指定值。
func setInputGain(Float)

//由用戶設置的系統範圍的輸出卷。
var outputVolume: Float

//當前音頻採樣率,單位爲赫茲。
var sampleRate: Double

//首選採樣率,單位爲赫茲。
var preferredSampleRate: Double

//設置音頻輸入和輸出的首選採樣率。
func setPreferredSampleRate(Double)

//音頻輸入的延遲,以秒爲單位。
var inputLatency: TimeInterval

//音頻輸出的延遲,以秒爲單位。
var outputLatency: TimeInterval

//當前I/O緩衝區持續時間(以秒爲單位)。
var ioBufferDuration: TimeInterval

//首選的I/O緩衝區持續時間(以秒爲單位)。
var preferredIOBufferDuration: TimeInterval

//設置首選音頻I/O緩衝區持續時間。
func setPreferredIOBufferDuration(TimeInterval)
複製代碼

8.10 設置聚合的I/O首選項

//設置音頻會話的聚合I/O配置首選項。
func setAggregatedIOPreference(AVAudioSession.IOType)

複製代碼

參考蘋果官方文檔:音頻會話章節

相關文章
相關標籤/搜索