iOS 音頻處理框架及重點 API 合集丨音視頻工程示例

vx 搜索『gjzkeyframe』 關注『關鍵幀Keyframe』來及時獲得最新的音視頻技術文章。

畢加索《手里捧著鴿子的孩子》像素版

這個公眾號會路線圖 式的遍歷分享音視頻技術音視頻基礎(完成)音視頻工具(完成)音視頻工程示例(進行中) → 音視頻工業(yè)實戰(zhàn)(準備)。

iOS/Android 客戶端開發(fā)同學如果想要開始學習音視頻開發(fā),最絲滑的方式是對音視頻基礎概念知識有一定了解后,再借助 iOS/Android 平臺的音視頻能力上手去實踐音視頻的采集 → 編碼 → 封裝 → 解封裝 → 解碼 → 渲染過程蜗搔,并借助音視頻工具來分析和理解對應的音視頻數據。

音視頻工程示例這個欄目的前面 6 篇 AVDemo 文章中,我們拆解了音頻采集 → 編碼 → 封裝 → 解封裝 → 解碼 → 渲染流程并基于 iOS 系統(tǒng) API 實現(xiàn)了 Demo:

你可以在關注本公眾號后抢腐,在公眾號發(fā)送消息『AVDemo』來獲取 Demo 的全部源碼。

如果你看完這些 Demo肴颊,對 iOS 平臺的音視頻開發(fā)多多少少會有一些認識了氓栈,在這個基礎上我們來總結一下 iOS 音頻處理框架,以及在前面的 Demo 中我們用到的主要 API 和數據結構有哪些婿着。

1授瘦、iOS 音頻框架

當我們想要了解 iOS 的音頻處理框架時,以下是我們能比較容易找到的兩張官方架構圖竟宋。它們分別出自 Audio Unit Hosting Guide for iOS[1] 和 Core Audio Overview[2] 這兩篇文檔提完。

iOS Audio Frameworks

iOS Audio Framework

Core Audio API Layers

Core Audio API Layers

但這兩篇文檔已經比較陳舊了,是多年之前的文檔丘侠,以至于和最新的 iOS 15 的框架有不少的出入徒欣。而新版本的 iOS 官方技術文檔也沒有給出比較清晰的音頻架構圖。所以在這里我們就按照 Demo 中涉及的系統(tǒng) API 來挑選介紹幾個相關的 Framework:

  • Audio Unit Framework
  • Core Media Framework
  • Audio Toolbox Framework
  • AVFoundation Framework

2蜗字、Audio Unit Framework

Audio Unit Framework[3]:最底層的音頻處理 API打肝,功能強大脂新,直接驅動底層硬件,提供快速粗梭、模塊化的音頻處理争便。當你要實現(xiàn)低延遲的音頻處理(比如 VoIP)、對合成聲音進行響應式的播放(比如音樂游戲断医、合成樂器聲音)敷扫、實現(xiàn)特定的音頻能力(比如回聲消除菱魔、混音、聲音均衡)、實現(xiàn)音頻處理鏈支持靈活組裝音頻處理單元時膛腐,你可以選擇使用 Audio Unit 的 API涣仿。

需要注意的是侣签,在最新的 iOS 系統(tǒng)庫架構中啊鸭,Audio Unit Framework 的實現(xiàn)都已經遷移到 Audio Toolbox Framework 中去了。

下面是 Audio Unit 框架的主要模塊:

1)Audio Component Services[4]:定義了發(fā)現(xiàn)荣挨、開啟和關閉音頻單元(audio unit)以及音頻編解碼器的接口男韧。

常用的數據類型:

  • AudioComponent[5]:表示音頻組件。一種音頻組件通常由 type默垄、subtype此虑、manufacturer 三屬性來唯一標識。
  • AudioComponentDescription[6]:表示音頻組件的描述口锭。其中 type朦前、subtype、manufacturer 三屬性組合起來標識一種音頻組件鹃操。
  • AudioComponentInstance[7]:表示音頻組件的實例韭寸。通常我們使用查找方法(AudioComponentFindNext)來找到符合描述的音頻組件,然后再去使用創(chuàng)建方法(AudioComponentInstanceNew)創(chuàng)建一個對應的音頻組件實例荆隘。

常用的接口:

  • AudioComponentFindNext(...)[8]:用于查找符合描述的音頻組件恩伺。
  • AudioComponentGetDescription(...)[9]:用于獲取一種音頻組件對應的描述。
  • AudioComponentInstanceNew(...)[10]:創(chuàng)建一個音頻組件實例椰拒。
  • AudioComponentInstanceDispose(...)[11]:釋放一個音頻組件實例晶渠。

2)Audio Unit Component Services[12]:提供了使用音頻單元(audio unit)的 C 語言接口。一個音頻單元(audio unit)是用來進行音頻數據處理或者音頻數據生成的插件單元燃观。要發(fā)現(xiàn)褒脯、開啟、關閉音頻單元(audio unit)則可以使用 Audio Component Services缆毁。

常用的數據類型:

  • AudioUnit[13]番川,typedef AudioComponentInstance AudioUnit;。AudioUnit 就是一種 AudioComponentInstance。
  • AudioUnitParameter[14]:表示 AudioUnit 的參數颁督,一個 AudioUnit 參數由 scope践啄、element、parameterID 三屬性定義沉御。
  • AudioUnitProperty[15]:表示 AudioUnit 的屬性往核,一個 AudioUnitProperty 由 scope、element嚷节、propertyID 三屬性定義。

常用的接口:

  • AudioUnitInitialize(...)[16]:初始化一個 AudioUnit虎锚。如果初始化成功硫痰,說明 input/output 的格式是可支持的,并且處于可以開始渲染的狀態(tài)窜护。
  • AudioUnitUninitialize(...)[17]:卸載一個 AudioUnit效斑。一旦一個 AudioUnit 被初始化后,要想改變它的狀態(tài)來響應某些環(huán)境變化柱徙,就需要先卸載缓屠。這時候會使得 AudioUnit 釋放它的資源。此后护侮,調用者可以重新配置這個 AudioUnit 來適配新的環(huán)境敌完,比如處理與之前不同的采樣率。在這之后羊初,可以重新初始化這個 AudioUnit 來應用這些更改滨溉。
  • AudioUnitRender(...)[18]:渲染輸入的音頻數據,數據量為 inNumberOfFrames长赞。渲染結果的數據存儲在 ioData 中晦攒。注意調用方需要提供音頻時間戳,這個時間戳應該滿足單調遞增得哆。
  • AudioUnitGetProperty(...)[19]:獲取 AudioUnit 的屬性脯颜。
  • AudioUnitSetProperty(...)[20]:設置 AudioUnit 的屬性。
  • AudioUnitGetParameter(...)[21]:獲取 AudioUnit 的參數贩据。
  • AudioUnitSetParameter(...)[22]:設置 AudioUnit 的參數栋操。

常用的回調:

  • AURenderCallback[23]:在以下幾種情況會被系統(tǒng)調用:當 AudioUnit 需要輸入采樣數據;在一個渲染操作前乐设;在一個渲染操作后讼庇。
  • AudioUnitPropertyListenerProc[24]:當一個指定的 AudioUnit 的 property 發(fā)生改變時,會被系統(tǒng)調用近尚。

3)Output Audio Unit Services[25]:提供了 start蠕啄、stop 用于 I/O 的音頻單元(通常是用于輸出的音頻單元)的 C 語言接口。

常用的接口:

  • AudioOutputUnitStart(...)[26]:啟動一個 I/O AudioUnit,同時會啟動與之連接的 AudioUnit Processing Graph歼跟。

  • AudioOutputUnitStop(...)[27]:關閉一個 I/O AudioUnit和媳,同時會關閉與之連接的 AudioUnit Processing Graph。

3哈街、Core Media Framework

Core Media Framework[28]:定義和封裝了 AVFoundation 等更上層的媒體框架需要的媒體處理流水線(包含時間信息)以及其中使用的接口和數據類型留瞳。使用 Core Media 層的接口和數據類型可以高效的處理媒體采樣數據、管理采樣數據隊列骚秦。下面是 Core Media 框架的主要模塊:

1)Sample Processing[29]:采樣數據處理她倘。常用的數據類型:

  • CMSampleBuffer[30]:系統(tǒng)用來在音視頻處理的 pipeline 中使用和傳遞媒體采樣數據的核心數據結構。你可以認為它是 iOS 音視頻處理 pipeline 中的流通貨幣作箍,攝像頭采集的視頻數據接口硬梁、麥克風采集的音頻數據接口、編碼和解碼數據接口胞得、讀取和存儲視頻接口荧止、視頻渲染接口等等,都以它作為參數阶剑。通常跃巡,CMSampleBuffer 中要么包含一個或多個媒體采樣的 CMBlockBuffer,要么包含一個 CVImageBuffer牧愁。
    • CMSampleBufferCreateReady(...)[31]:基于媒體數據創(chuàng)建一個 CMSampleBuffer素邪。
    • CMSampleBufferCreate(...)[32]:創(chuàng)建一個 CMSampleBuffer,支持設置數據已準備好的回調递宅。
    • CMSampleBufferSetDataBufferFromAudioBufferList(...)[33]:為指定的 CMSampleBuffer 創(chuàng)建其對應的 CMBlockBuffer娘香,其中的數據拷貝自 AudioBufferList。
    • CMSampleBufferGetFormatDescription(...)[34]:返回 CMSampleBuffer 中的采樣數據對應的 CMFormatDescription办龄。
    • CMSampleBufferGetDataBuffer(...)[35]:返回 CMSampleBuffer 中的 CMBlockBuffer烘绽。注意調用方不會持有返回的 CMBlockBuffer,如果想要維護指向它的指針俐填,需要顯式 retain 一下安接。
    • CMSampleBufferGetPresentationTimeStamp(...)[36]:獲取 CMSampleBuffer 中所有采樣的最小的 pts 時間戳。
  • CMBlockBuffer[37]:一個或多個媒體采樣的的裸數據英融。其中可以封裝:音頻采集后盏檐、編碼后、解碼后的數據(如:PCM 數據驶悟、AAC 數據)胡野;視頻編碼后的數據(如:H.264 數據)。
    • CMBlockBufferCreateWithMemoryBlock(...)[38]:基于內存數據創(chuàng)建一個 CMBlockBuffer痕鳍。
    • CMBlockBufferGetDataPointer(...)[39]:獲取訪問 CMBlockBuffer 中數據的地址硫豆。
  • CMFormatDescription[40]:用于描述 CMSampleBuffer 中采樣的格式信息龙巨。
    • CMFormatDescriptionCreate(...)[41]:創(chuàng)建一個 CMFormatDescription。
  • CMAudioFormatDescription[42]:typedef CMFormatDescriptionRef CMAudioFormatDescriptionRef;熊响。CMAudioFormatDescription 是一種 CMFormatDescriptionRef旨别。
    • CMAudioFormatDescriptionCreate(...)[43]:基于 AudioStreamBasicDescription 來創(chuàng)建一個 CMAudioFormatDescription。
    • CMAudioFormatDescriptionGetStreamBasicDescription(...)[44]:返回一個指向 CMFormatDescription(通常應該是一個 CMAudioFormatDescription) 中的 AudioStreamBasicDescription 的指針汗茄。如果是非音頻格式秸弛,就返回 NULL。
  • CMAttachment[45]:為 CMSampleBuffer 添加支持的 metadata洪碳。

這里我們還要補充介紹 CoreAudioTypes Framework 中的幾種數據類型:

  • AudioStreamBasicDescription[46]:用于描述音頻流數據格式信息递览,比如采樣位深、聲道數瞳腌、采樣率非迹、每幀字節(jié)數、每包幀數纯趋、每包字節(jié)數、格式標識等冷离。
  • AudioBuffer[47]:存儲并描述音頻數據的緩沖區(qū)吵冒。mData 中存儲著數據∥靼可以存儲兩種不同類型的音頻:1)單聲道音頻數據痹栖;2)多聲道的交錯音頻數據,這時候 mNumberChannels 指定了聲道數瞭空。
  • AudioBufferList[48]:一組 AudioBuffer揪阿。
  • AudioTimeStamp[49]:從多維度來表示一個時間戳的數據結構。

2)Time Representation[50]:時間信息表示咆畏。常用的數據類型:

  • CMTime[51]:用 value/timescale 的方式表示時間南捂。這樣可以解決浮點運算時的精度損失問題。timescale 表示時間刻度旧找,通常在處理視頻內容時常見的時間刻度為 600溺健,這是大部分常用視頻幀率 24fps、25fps钮蛛、30fps 的公倍數鞭缭,音頻數據常見的時間刻度就是采樣率,比如 44100 或 48000魏颓。
  • CMTimeRange[52]:用 start+duration 的方式表示一段時間岭辣。
  • CMSampleTimingInfo[53]:一個 CMSampleBuffer 的時間戳信息,包括 pts甸饱、dts沦童、duration。

3)Queues[54]:數據容器。常用的數據類型:

  • CMSimpleQueue[55]:一個簡單地搞动、無鎖的 FIFO 隊列躏精,可以放 (void *) 元素,元素不能是 NULL 或 0鹦肿,如果元素是指向分配內存的指針矗烛,其內存生命周期要在外面自己管理÷崂#可以用作音視頻采樣數據(CMSampleBufferRef)的隊列瞭吃,不過要自己加鎖。
  • CMBufferQueue[56]:支持存儲任何 CFTypeRef 類型的數據涣旨,但是數據類型需要有 duration 的概念歪架,在創(chuàng)建 CMBufferQueue 的時候,會有一些回調霹陡,其中一個必須的回調是要返回隊列中對象的 duration和蚪。CMBufferQueue 是設計用于在生產者/消費者模型中在不同的線程中讀寫數據。通常是兩個線程(一個是生產者入隊線程烹棉,一個是消費者出隊線程)攒霹,當然更多的線程也是可以的。
  • CMMemoryPool[57]:內存池容器浆洗,對使用大塊的內存有優(yōu)化催束。一個 CMMemoryPool 的實例實際上維護一個最近釋放內存的池子用于內存分配服務。這樣的目的是加快隨后的內存分配伏社。在需要重復分配大塊內存時抠刺,比如輸出視頻編碼數據,可以使用這個數據結構摘昌。

4速妖、Audio Toolbox Framework

Audio Toolbox Framework[58]:提供了音頻錄制、播放聪黎、流解析买优、編碼格式轉換、Audio Session 管理等功能接口挺举。下面是 Audio Toolbox 框架的主要模塊:

1)Audio Units[59]:音頻單元杀赢。關于 Audio Unit 的內容,還可以參考上面講到的 Audio Unit Framework湘纵。

  • Audio Unit v3 Plug-Ins[60]:基于 AUv3 應用擴展接口來提供自定義的音效脂崔、樂器及其他音頻能力。
  • Audio Components[61]:定義了發(fā)現(xiàn)梧喷、加載砌左、配置和關閉音頻組件(包括音頻單元(audio unit)脖咐、音頻編解碼器(audio codec))的接口。
  • Audio Unit v2 (C) API[62]:配置一個音頻單元(audio unit)以及進行音頻渲染汇歹。
  • Audio Unit Properties[63]:獲取有關內置混音器屁擅、均衡器、濾波器产弹、特效及音頻應用擴展的信息派歌。
  • Audio Unit Voice I/O[64]:配置系統(tǒng)語音處理、響應語音事件痰哨。

2)Playback and Recording[65]:音頻播放和錄制胶果。

  • Audio Queue Services[66]:提供了簡單的、低開銷的方式來錄制和播放音頻的 C 語言接口斤斧。支持 Linear PCM早抠、AAC 的錄制和播放。實現(xiàn)了連接音頻硬件撬讽、管理內存蕊连、根據需要使用解碼器解碼音頻、調解錄音和播放游昼。但是要實現(xiàn)低延遲咪奖、回聲消除、混音等功能酱床,還得使用 AudioUnit。
  • Audio Services[67]:提供了一組 C 語言接口來實現(xiàn)播放短聲或觸發(fā) iOS 設備的振動效果趟佃。
  • Music Player[68]:支持播放一組音軌扇谣,并管理播放的各種的事件。

3)Audio Files and Formats[69]:音頻文件和格式闲昭。

  • Audio Format Services[70]:獲取音頻格式和編解碼器的信息罐寨。
  • Audio File Services[71]:從磁盤或內存讀寫各種音頻數據。
  • Extended Audio File Services[72]:通過組合 Audio File Services 和 Audio Converter Services 來提供讀寫音頻編碼文件或 LPCM 音頻文件序矩。
  • Audio File Stream Services[73]:解析音頻流數據鸯绿。
  • Audio File Components[74]:獲取音頻文件格式以及文件中包含的數據的信息。
  • Core Audio File Format[75]:解析 Core Audio 文件的結構簸淀。

4)Utilities[76]:其他音頻功能支持瓶蝴。

  • Audio Converter Services[77]:音頻編解碼。支持 LPCM 各種格式轉換租幕,以及 LPCM 與編碼格式(如 AAC)的轉換舷手。常用的接口:
    • AudioConverterNew(...)[78]:根據指定的輸入和輸出音頻格式創(chuàng)建對應的轉換器(編解碼器)實例。

    • AudioConverterNewSpecific(...)[79]:根據指定的 codec 來創(chuàng)建一個新的音頻轉換器(編解碼器)實例劲绪。

    • AudioConverterReset(...)[80]:重置音頻轉換器(編解碼器)實例男窟,并清理它的緩沖區(qū)盆赤。

    • AudioConverterDispose(...)[81]:釋放音頻轉換器(編解碼器)實例。

    • AudioConverterGetProperty(...)[82]:獲取音頻轉換器(編解碼器)的屬性歉眷。

    • AudioConverterSetProperty(...)[83]:設置音頻轉換器(編解碼器)的屬性牺六。

    • AudioConverterConvertBuffer(...)[84]:只用于一種特殊的情況下將音頻數據從一種 LPCM 格式轉換為另外一種,并且前后采樣率一致汗捡。這個接口不支持大多數壓縮編碼格式淑际。

    • AudioConverterFillComplexBuffer(...)[85]:轉換(編碼)回調函數提供的音頻數據,支持不交錯和包格式凉唐。大部分情況下都建議用這個接口庸追,除非是要將音頻數據從一種 LPCM 格式轉換為另外一種。

    • AudioConverterComplexInputDataProc[86]:為 AudioConverterFillComplexBuffer(...) 接口提供輸入數據的回調台囱。

    • Audio Codec[87]:提供了支持將音頻數據進行編碼格式轉換的 API淡溯。具體支持哪些編碼格式取決于系統(tǒng)提供了哪些編解碼器。

5簿训、AVFoundation Framework

AVFoundation Framework[88] 是更上層的面向對象的一個音視頻處理框架咱娶。它提供了音視頻資源管理、相機設備管理强品、音視頻處理膘侮、系統(tǒng)級音頻交互管理的能力,功能非常強大的榛。如果對其功能進行細分琼了,可以分為如下幾個模塊:

  • Assets,音視頻資源管理夫晌。
  • Playback雕薪,媒體播放及自定義播放行為支持。
  • Capture晓淀,內置及外置的相機所袁、麥克風等采集設備管理,圖片凶掰、音視頻錄制燥爷。
  • Editing,音視頻編輯懦窘。
  • Audio前翎,音頻播放、錄制和處理畅涂,App 系統(tǒng)音頻行為配置鱼填。
  • Speech,文本語音轉換毅戈。

在我們前面的 Demo 中封裝 Muxer 和 Demuxer 及設置 AudioSession 時會用到 AVFoundation Framework 的一些能力苹丸,我們這里對應地介紹一下愤惰。

  • AVAssetWriter[89]:支持將媒體數據寫入 QuickTime 或 MPEG-4 格式的文件中,支持對多軌道的媒體數據進行交錯處理來提高播放和存儲的效率赘理,支持對媒體采樣進行轉碼宦言,支持寫入 metadata。需要注意的是商模,一個 AVAssetWriter 實例只能對應寫一個文件奠旺,如果要寫入多個文件,需要創(chuàng)建多個 AVAssetWriter 實例施流。
    • canAddInput:[90]:檢查 AVAssetWriter 是否支持添加對應的 AVAssetWriterInput响疚。
    • addInput:[91]:給 AVAssetWriter 添加一個 AVAssetWriterInput。注意必須在 AVAssetWriter 開始寫入之前添加瞪醋。
    • startWriting[92]:開始寫入忿晕。必須在配置好 AVAssetWriter 添加完 AVAssetWriterInput 做好準備后再調用這個方法。在調用完這個方法后银受,需要調用 startSessionAtSourceTime: 開始寫入會話践盼,此后就可以使用對應的 AVAssetWriterInput 來寫入媒體采樣數據。
    • startSessionAtSourceTime:[93]:開啟寫入會話宾巍。在 startWriting 后調用咕幻,在寫入媒體采樣數據之前調用。
    • endSessionAtSourceTime:[94]:結束寫入會話顶霞。結束時間是會話結束時樣本數據在時間軸上的時刻肄程。如果沒有顯示調用這個方法,系統(tǒng)會在你調用 finishWritingWithCompletionHandler:結束寫入時自動調用选浑。
    • finishWritingWithCompletionHandler:[95]:標記 AVAssetWriter 的所有 input 為結束蓝厌,完成寫入。為了保證 AVAssetWriter 完成所有采樣數據的寫入鲜侥,要在調用添加數據正確返回后調用這個方法。
    • cancelWriting[96]:取消創(chuàng)建輸出文件诸典。如果 AVAssetWriter 的狀態(tài)是 Failed 或 Completed描函,調用這個方法無效,否則狐粱,調用它會阻塞調用線程舀寓,直到會話取消完成。如果 AVAssetWriter 已經創(chuàng)建了輸出文件肌蜻,調用這個方法會刪除這個文件互墓。
  • AVAssetWriterInput[97]:用于向 AVAssetWriter 實例的輸出文件的一個軌道添加媒體采樣數據。一個實例只能對應一個軌道媒體數據或 metadata 數據的寫入蒋搜,當使用多個實例向多個軌道寫入數據時乎澄,需要注意檢查 AVAssetWriterInput 的 readyForMoreMediaData 屬性醋寝。
    • expectsMediaDataInRealTime[98]:輸入是否為實時數據源讨便,比如相機采集。當設置這個值為 YES 時券盅,會優(yōu)化用于實時使用的輸入來精準計算 readyForMoreMediaData 的狀態(tài)。
    • readyForMoreMediaData[99]:表示 AVAssetWriterInput 是否已經準備好接收媒體數據膛檀。
    • requestMediaDataWhenReadyOnQueue:usingBlock:[100]:告訴 AVAssetWriterInput 在方便的時候去請求數據并寫入輸出文件锰镀。在對接拉取式的數據源時,可以用這個方法咖刃。
    • appendSampleBuffer:[101]:通過 AVAssetWriterInput 向輸出文件添加媒體數據泳炉,但是添加之前媒體數據的順序需要自己處理。注意嚎杨,調用這個方法添加采樣數據后花鹅,不要更改采樣數據的內容。
    • markAsFinished[102]:標記 AVAssetWriterInput 為完成磕潮,表示已經完成向它添加媒體數據了翠胰。
  • AVAssetReader[103]:用于從 AVAsset 資源中讀取媒體數據。這個 AVAsset 可以是 QuickTime 或 MPEG-4 文件自脯,也可以是編輯創(chuàng)作的 AVComposition之景。
    • canAddOutput:[104]:檢查 AVAssetReader 是否支持添加對應的 AVAssetReaderOutput。
    • addOutput:[105]:給 AVAssetReader 添加一個 AVAssetReaderOutput膏潮。注意必須在 AVAssetReader 開始讀取之前添加锻狗。
    • startReading[106]:開始讀取。
    • cancelReading[107]:在讀完數據之前取消讀取可以調用這個接口焕参。
  • AVAssetReaderOutput[108]:一個抽象類轻纪,定義了從 AVAsset 資源中讀取媒體采樣數據的接口。通常我們可以使用 AVAssetReaderTrackOutput叠纷、AVAssetReaderVideoCompositionOutput 等具體的實現(xiàn)類刻帚。
  • AVAssetReaderTrackOutput[109]:
    • alwaysCopiesSampleData[110]:是否總是拷貝采樣數據。如果要修改讀取的采樣數據涩嚣,可以設置 YES崇众,否則就設置 NO,這樣性能會更好航厚。
    • copyNextSampleBuffer[111]:從 Output 拷貝下一個 CMSampleBuffer顷歌。
  • AVAudioSession[112]:在最新版本的 iOS 系統(tǒng)庫中,AVAudioSession 已經遷移到 AVFAudio Framework 中了幔睬。AVAudioSession 是系統(tǒng)用來管理 App 對音頻硬件資源的使用的眯漩,比如:設置當前 App 與其他 App 同時使用音頻時,是否混音麻顶、打斷或降低其他 App 的聲音赦抖;手機靜音鍵打開時是否還可以播放聲音舱卡;指定音頻輸入或者輸出設備;是否支持錄制或邊錄制邊播放摹芙;聲音被打斷時的通知灼狰。我們這里只簡單介紹下 Demo 中用到的接口:
    • setCategory:withOptions:error:[113]:設置 AudioSession 的類型和選項參數。比如類型為 AVAudioSessionCategoryPlayback 表示支持播放浮禾;AVAudioSessionCategoryPlayAndRecord 表示同時支持播放和錄制等等交胚。
    • setMode:error:[114]:設置 AudioSession 的模式。AudioSession 的類型和模式一起決定了 App 如何使用音頻盈电。通常需要在激活 AudioSession 之前設置類型和模式蝴簇。比如模式為 AVAudioSessionModeVideoRecording 表示當期要錄制視頻;AVAudioSessionModeVoiceChat 表示語音聊天匆帚。
    • setActive:withOptions:error:[115]:激活或釋放 AudioSession 的使用熬词。

以上這些框架及 API 基本上可以覆蓋我們在前面的 Demo 中用到的能力了。

參考資料

[1]

Audio Unit Hosting Guide for iOS: https://developer.apple.com/library/archive/documentation/MusicAudio/Conceptual/AudioUnitHostingGuide_iOS/AudioUnitHostingFundamentals/AudioUnitHostingFundamentals.html

[2]

Core Audio Overview: https://developer.apple.com/library/archive/documentation/MusicAudio/Conceptual/CoreAudioOverview/CoreAudioEssentials/CoreAudioEssentials.html

[3]

Audio Unit: https://developer.apple.com/documentation/audiounit?language=objc

[4]

Audio Component Services: https://developer.apple.com/documentation/audiounit/audio_component_services?language=objc

[5]

AudioComponent: https://developer.apple.com/documentation/audiotoolbox/audiocomponent?language=objc

[6]

AudioComponentDescription: https://developer.apple.com/documentation/audiotoolbox/audiocomponentdescription?language=objc

[7]

AudioComponentInstance: https://developer.apple.com/documentation/audiotoolbox/audiocomponentinstance?language=objc

[8]

AudioComponentFindNext(...): https://developer.apple.com/documentation/audiotoolbox/1410445-audiocomponentfindnext?language=objc

[9]

AudioComponentGetDescription(...): https://developer.apple.com/documentation/audiotoolbox/1410523-audiocomponentgetdescription?language=objc

[10]

AudioComponentInstanceNew(...): https://developer.apple.com/documentation/audiotoolbox/1410465-audiocomponentinstancenew?language=objc

[11]

AudioComponentInstanceDispose(...): https://developer.apple.com/documentation/audiotoolbox/1410508-audiocomponentinstancedispose

[12]

Audio Unit Component Services: https://developer.apple.com/documentation/audiounit/audio_component_services?language=objc

[13]

AudioUnit: https://developer.apple.com/documentation/audiotoolbox/audiounit?language=objc

[14]

AudioUnitParameter: https://developer.apple.com/documentation/audiotoolbox/audiounitparameter?language=objc

[15]

AudioUnitProperty: https://developer.apple.com/documentation/audiotoolbox/audiounitproperty?language=objc

[16]

AudioUnitInitialize(...): https://developer.apple.com/documentation/audiotoolbox/1439851-audiounitinitialize?language=objc

[17]

AudioUnitUninitialize(...): https://developer.apple.com/documentation/audiotoolbox/1438415-audiounituninitialize?language=objc

[18]

AudioUnitRender(...): https://developer.apple.com/documentation/audiotoolbox/1438430-audiounitrender?language=objc

[19]

AudioUnitGetProperty(...): https://developer.apple.com/documentation/audiotoolbox/1439840-audiounitgetproperty?language=objc

[20]

AudioUnitSetProperty(...): https://developer.apple.com/documentation/audiotoolbox/1440371-audiounitsetproperty?language=objc

[21]

AudioUnitGetParameter(...): https://developer.apple.com/documentation/audiotoolbox/1440055-audiounitgetparameter?language=objc

[22]

AudioUnitSetParameter(...): https://developer.apple.com/documentation/audiotoolbox/1438454-audiounitsetparameter?language=objc

[23]

AURenderCallback: https://developer.apple.com/documentation/audiotoolbox/aurendercallback?language=objc

[24]

AudioUnitPropertyListenerProc: https://developer.apple.com/documentation/audiotoolbox/audiounitpropertylistenerproc?language=objc

[25]

Output Audio Unit Services: https://developer.apple.com/documentation/audiounit/output_audio_unit_services?language=objc

[26]

AudioOutputUnitStart(...): https://developer.apple.com/documentation/audiotoolbox/1439763-audiooutputunitstart?language=objc

[27]

AudioOutputUnitStop(...): https://developer.apple.com/documentation/audiotoolbox/1440513-audiooutputunitstop?language=objc

[28]

Core Media: https://developer.apple.com/documentation/coremedia?language=objc

[29]

Sample Processing: https://developer.apple.com/documentation/coremedia?language=objc

[30]

CMSampleBuffer: https://developer.apple.com/documentation/coremedia/cmsamplebuffer-u71?language=objc

[31]

CMSampleBufferCreateReady(...): https://developer.apple.com/documentation/coremedia/1489513-cmsamplebuffercreateready?language=objc

[32]

CMSampleBufferCreate(...): https://developer.apple.com/documentation/coremedia/1489723-cmsamplebuffercreate?language=objc

[33]

CMSampleBufferSetDataBufferFromAudioBufferList(...): https://developer.apple.com/documentation/coremedia/1489725-cmsamplebuffersetdatabufferfroma?language=objc

[34]

CMSampleBufferGetFormatDescription(...): https://developer.apple.com/documentation/coremedia/1489185-cmsamplebuffergetformatdescripti?language=objc

[35]

CMSampleBufferGetDataBuffer(...): https://developer.apple.com/documentation/coremedia/1489629-cmsamplebuffergetdatabuffer?language=objc

[36]

CMSampleBufferGetPresentationTimeStamp(...): https://developer.apple.com/documentation/coremedia/1489252-cmsamplebuffergetpresentationtim?language=objc

[37]

CMBlockBuffer: https://developer.apple.com/documentation/coremedia/cmblockbuffer-u9i?language=objc

[38]

CMBlockBufferCreateWithMemoryBlock(...): https://developer.apple.com/documentation/coremedia/1489501-cmblockbuffercreatewithmemoryblo?language=objc

[39]

CMBlockBufferGetDataPointer(...): https://developer.apple.com/documentation/coremedia/1489264-cmblockbuffergetdatapointer?language=objc

[40]

CMFormatDescription: https://developer.apple.com/documentation/coremedia/cmformatdescription-u8g?language=objc

[41]

CMFormatDescriptionCreate(...): https://developer.apple.com/documentation/coremedia/1489182-cmformatdescriptioncreate?language=objc

[42]

CMAudioFormatDescription: https://developer.apple.com/documentation/coremedia/cmaudioformatdescription?language=objc

[43]

CMAudioFormatDescriptionCreate(...): https://developer.apple.com/documentation/coremedia/1489522-cmaudioformatdescriptioncreate?language=objc

[44]

CMAudioFormatDescriptionGetStreamBasicDescription(...): https://developer.apple.com/documentation/coremedia/1489226-cmaudioformatdescriptiongetstrea?language=objc

[45]

CMAttachment: https://developer.apple.com/documentation/coremedia/cmattachment?language=objc

[46]

AudioStreamBasicDescription: https://developer.apple.com/documentation/coreaudiotypes/audiostreambasicdescription?language=objc

[47]

AudioBuffer: https://developer.apple.com/documentation/coreaudiotypes/audiobuffer?language=objc

[48]

AudioBufferList: https://developer.apple.com/documentation/coreaudiotypes/audiobufferlist?language=objc

[49]

AudioTimeStamp: https://developer.apple.com/documentation/coreaudiotypes/audiotimestamp?language=objc

[50]

Time Representation: https://developer.apple.com/documentation/coremedia?language=objc

[51]

CMTime: https://developer.apple.com/documentation/coremedia/cmtime-u58?language=objc

[52]

CMTimeRange: https://developer.apple.com/documentation/coremedia/cmtimerange-qts?language=objc

[53]

CMSampleTimingInfo: https://developer.apple.com/documentation/coremedia/cmsampletiminginfo?language=objc

[54]

Queues: https://developer.apple.com/documentation/coremedia?language=objc

[55]

CMSimpleQueue: https://developer.apple.com/documentation/coremedia/cmsimplequeue?language=objc

[56]

CMBufferQueue: https://developer.apple.com/documentation/coremedia/cmbufferqueue?language=objc

[57]

CMMemoryPool: https://developer.apple.com/documentation/coremedia/cmmemorypool-u89?language=objc

[58]

Audio Toolbox: https://developer.apple.com/documentation/audiotoolbox?language=objc

[59]

Audio Units: https://developer.apple.com/documentation/audiotoolbox?language=objc

[60]

Audio Unit v3 Plug-Ins: https://developer.apple.com/documentation/audiotoolbox/audio_unit_v3_plug-ins?language=objc

[61]

Audio Components: https://developer.apple.com/documentation/audiotoolbox/audio_components?language=objc

[62]

Audio Unit v2 (C) API: https://developer.apple.com/documentation/audiotoolbox/audio_unit_v2_c_api?language=objc

[63]

Audio Unit Properties: https://developer.apple.com/documentation/audiotoolbox/audio_unit_properties?language=objc

[64]

Audio Unit Voice I/O: https://developer.apple.com/documentation/audiotoolbox/audio_unit_voice_i_o?language=objc

[65]

Playback and Recording: https://developer.apple.com/documentation/audiotoolbox?language=objc

[66]

Audio Queue Services: https://developer.apple.com/documentation/audiotoolbox/audio_queue_services?language=objc

[67]

Audio Services: https://developer.apple.com/documentation/audiotoolbox/audio_services?language=objc

[68]

Music Player: https://developer.apple.com/documentation/audiotoolbox/music_player?language=objc

[69]

Audio Files and Formats: https://developer.apple.com/documentation/audiotoolbox?language=objc

[70]

Audio Format Services: https://developer.apple.com/documentation/audiotoolbox/audio_format_services?language=objc

[71]

Audio File Services: https://developer.apple.com/documentation/audiotoolbox/audio_file_services?language=objc

[72]

Extended Audio File Services: https://developer.apple.com/documentation/audiotoolbox/extended_audio_file_services?language=objc

[73]

Audio File Stream Services: https://developer.apple.com/documentation/audiotoolbox/audio_file_stream_services?language=objc

[74]

Audio File Components: https://developer.apple.com/documentation/audiotoolbox/audio_file_components?language=objc

[75]

Core Audio File Format: https://developer.apple.com/documentation/audiotoolbox/core_audio_file_format?language=objc

[76]

Utilities: https://developer.apple.com/documentation/audiotoolbox?language=objc

[77]

Audio Converter Services: https://developer.apple.com/documentation/audiotoolbox/audio_converter_services?language=objc

[78]

AudioConverterNew(...): https://developer.apple.com/documentation/audiotoolbox/1502936-audioconverternew?language=objc

[79]

AudioConverterNewSpecific(...): https://developer.apple.com/documentation/audiotoolbox/1503356-audioconverternewspecific?language=objc

[80]

AudioConverterReset(...): https://developer.apple.com/documentation/audiotoolbox/1503102-audioconverterreset?language=objc

[81]

AudioConverterDispose(...): https://developer.apple.com/documentation/audiotoolbox/1502671-audioconverterdispose?language=objc

[82]

AudioConverterGetProperty(...): https://developer.apple.com/documentation/audiotoolbox/1502731-audioconvertergetproperty?language=objc

[83]

AudioConverterSetProperty(...): https://developer.apple.com/documentation/audiotoolbox/1501675-audioconvertersetproperty?language=objc

[84]

AudioConverterConvertBuffer(...): https://developer.apple.com/documentation/audiotoolbox/1503345-audioconverterconvertbuffer?language=objc

[85]

AudioConverterFillComplexBuffer(...): https://developer.apple.com/documentation/audiotoolbox/1503098-audioconverterfillcomplexbuffer?language=objc

[86]

AudioConverterComplexInputDataProc: https://developer.apple.com/documentation/audiotoolbox/audioconvertercomplexinputdataproc?language=objc

[87]

Audio Codec: https://developer.apple.com/documentation/audiotoolbox/audio_codec?language=objc

[88]

AVFoundation Framework: https://developer.apple.com/documentation/avfoundation?language=objc

[89]

AVAssetWriter: https://developer.apple.com/documentation/avfoundation/avassetwriter?language=objc

[90]

canAddInput:: https://developer.apple.com/documentation/avfoundation/avassetwriter/1387863-canaddinput?language=objc

[91]

addInput:: https://developer.apple.com/documentation/avfoundation/avassetwriter/1390389-addinput?language=objc

[92]

startWriting: https://developer.apple.com/documentation/avfoundation/avassetwriter/1386724-startwriting?language=objc

[93]

startSession(atSourceTime:): https://developer.apple.com/documentation/avfoundation/avassetwriter/1389908-startsessionatsourcetime?language=objc

[94]

endSessionAtSourceTime:: https://developer.apple.com/documentation/avfoundation/avassetwriter/1389921-endsessionatsourcetime?language=objc

[95]

finishWritingWithCompletionHandler:: https://developer.apple.com/documentation/avfoundation/avassetwriter/1390432-finishwriting?language=objc

[96]

cancelWriting: https://developer.apple.com/documentation/avfoundation/avassetwriter/1387234-cancelwriting?language=objc

[97]

AVAssetWriterInput: https://developer.apple.com/documentation/avfoundation/avassetwriterinput?language=objc

[98]

expectsMediaDataInRealTime: https://developer.apple.com/documentation/avfoundation/avassetwriterinput/1387827-expectsmediadatainrealtime?language=objc

[99]

readyForMoreMediaData: https://developer.apple.com/documentation/avfoundation/avassetwriterinput/1389084-readyformoremediadata?language=objc

[100]

requestMediaDataWhenReadyOnQueue:usingBlock:: https://developer.apple.com/documentation/avfoundation/avassetwriterinput?language=objc

[101]

appendSampleBuffer:: https://developer.apple.com/documentation/avfoundation/avassetwriterinput/1389566-appendsamplebuffer?language=objc

[102]

markAsFinished: https://developer.apple.com/documentation/avfoundation/avassetwriterinput/1390122-markasfinished?language=objc

[103]

AVAssetReader: https://developer.apple.com/documentation/avfoundation/avassetreader?language=objc

[104]

canAddOutput:: https://developer.apple.com/documentation/avfoundation/avassetreader/1387485-canaddoutput?language=objc

[105]

addOutput:: https://developer.apple.com/documentation/avfoundation/avassetreader/1390110-addoutput?language=objc

[106]

startReading: https://developer.apple.com/documentation/avfoundation/avassetreader/1390286-startreading?language=objc

[107]

cancelReading: https://developer.apple.com/documentation/avfoundation/avassetreader/1390258-cancelreading?language=objc

[108]

AVAssetReaderOutput: https://developer.apple.com/documentation/avfoundation/avassetreaderoutput?language=objc

[109]

AVAssetReaderTrackOutput: https://developer.apple.com/documentation/avfoundation/avassetreadertrackoutput?language=objc

[110]

alwaysCopiesSampleData: https://developer.apple.com/documentation/avfoundation/avassetreaderoutput/1389189-alwayscopiessampledata?language=objc

[111]

copyNextSampleBuffer: https://developer.apple.com/documentation/avfoundation/avassetreaderoutput/1385732-copynextsamplebuffer?language=objc

[112]

AVAudioSession: https://developer.apple.com/documentation/avfaudio/avaudiosession?language=objc

[113]

setCategory:withOptions:error:: https://developer.apple.com/documentation/avfaudio/avaudiosession/1616442-setcategory?language=objc

[114]

setMode:error:: https://developer.apple.com/documentation/avfaudio/avaudiosession/1616614-setmode?language=objc

[115]

setActive:withOptions:error:: https://developer.apple.com/documentation/avfaudio/avaudiosession?language=objc

- 完 -

推薦閱讀

《iOS AVDemo(6):音頻渲染》

《iOS AVDemo(5):音頻解碼》

《iOS AVDemo(4):音頻解封裝》

《iOS AVDemo(3):音頻封裝》

《iOS AVDemo(2):音頻編碼》

《iOS AVDemo(1):音頻采集》

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末吸重,一起剝皮案震驚了整個濱河市互拾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嚎幸,老刑警劉巖颜矿,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異嫉晶,居然都是意外死亡骑疆,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門替废,熙熙樓的掌柜王于貴愁眉苦臉地迎上來箍铭,“玉大人,你說我怎么就攤上這事椎镣≌┗穑” “怎么了?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵状答,是天一觀的道長冷守。 經常有香客問我,道長剪况,這世上最難降的妖魔是什么教沾? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任蒲跨,我火速辦了婚禮译断,結果婚禮上,老公的妹妹穿的比我還像新娘或悲。我一直安慰自己孙咪,他們只是感情好堪唐,可當我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著翎蹈,像睡著了一般淮菠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上荤堪,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天合陵,我揣著相機與錄音,去河邊找鬼澄阳。 笑死拥知,一個胖子當著我的面吹牛,可吹牛的內容都是我干的碎赢。 我是一名探鬼主播低剔,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼肮塞!你這毒婦竟也來了襟齿?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤枕赵,失蹤者是張志新(化名)和其女友劉穎猜欺,沒想到半個月后,有當地人在樹林里發(fā)現(xiàn)了一具尸體烁设,經...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡替梨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了装黑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片副瀑。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖恋谭,靈堂內的尸體忽然破棺而出糠睡,到底是詐尸還是另有隱情,我是刑警寧澤疚颊,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布狈孔,位于F島的核電站,受9級特大地震影響材义,放射性物質發(fā)生泄漏均抽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一其掂、第九天 我趴在偏房一處隱蔽的房頂上張望油挥。 院中可真熱鬧,春花似錦、人聲如沸深寥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽惋鹅。三九已至则酝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間闰集,已是汗流浹背沽讹。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留武鲁,地道東北人妥泉。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像洞坑,于是被迫代替她去往敵國和親盲链。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內容