WebRTC手記之本地音頻采集


轉載請注明出處:http://www.cnblogs.com/fangkm/p/4374668.html 

上一篇博文介紹了本地視頻采集,這一篇就介紹下音頻采集流程,也是先介紹WebRTC原生的音頻采集,再介紹Chromium源碼對它的定制。

1. WebRTC原生音頻采集

先介紹一下WebRTC中與音頻采集貌似相關的接口概念:

結構上看起來是不是和視頻Track的結構類似?不過前面提過,如果你以對稱的思維,在此結構中找出與視頻track相似的采集源和輸出源,那就肯定無功而返了,LocalAudioSource對AudioSourceInterface的實現就是一個空實現,沒有了音頻源,那音頻處理接口AudioProcessorInterface和輸出接口AudioRenderer都成了無米之炊了。這些接口先擺在這,可能類似於AudioCapturer的框架正在實現的途中,也可能這些接口有別的用處,比如遠程音頻流的抽象等,這里就暫且擱置,先記下有這回事吧。這里只談WebRTC本地音頻的采集處理。前面介紹音視頻接口的時候也提到的,本地音頻的采集由AudioDeviceModule接口統一封裝:

AudioDeviceModule是個大而全的接口,恨不得將所有音頻相關的接口都封裝在里面(實際也差不多了),具體包括:枚舉音頻采集設備(Record)和播放設備(Playout)、設置當前的采集設備/播放設備、開始/停止音頻的采集/播放、設置音頻增益控制開關(AGC)等。AudioTransport是個關鍵的對外接口,負責音頻數據的傳入(調用NeedMorePlayData方法,供Playout使用)和輸出(調用RecordedDataIsAvailable方法,數據由Record采集操作產生)。

AudioDeviceModuleImpl實現了AudioDeviceModule接口,創建的時候調用CreatePlatformSpecificObjects方法創建平台相關的AudioDeviceGeneric接口實現。該接口抽象了音頻的采集和播放邏輯,在Windows平台下有兩種實現方案:

  •   AudioDeviceWindowsWave實現的是傳統的Windows Wave APIs方案。
  •  AudioDeviceWindowsCore實現的是Vista之后才支持的Windows Core Audio APIs方案。

此外,AudioDeviceModuleImpl還維護了一個AudioDeviceBuffer對象來管理音頻數據的緩沖區,由它直接與對外接口AudioTransport交互。比如:

  •  當AudioDeviceWindowsWave或者AudioDeviceWindowsCore需要播放音頻數據的時候,會調用AudioDeviceBuffer的RequestPlayoutData方法請求播放數據,然后通過GetPlayoutData方法來獲取剛請求到的數據。AudioDeviceBuffer的RequestPlayoutData就是調用AudioTransport接口的NeedMorePlayData方法來請求待播放的音頻流數據。
  •  當AudioDeviceWindowsWave或者AudioDeviceWindowsCore采集到音頻數據后,會調用AudioDeviceBuffer的SetRecordedBuffer方法將采集到的音頻數據傳遞進去,然后調用DeliverRecordedData方法來派發出去,該派發方法就是通過調用AudioTransport接口的RecordedDataIsAvailable來實現。

總之,音頻采集模塊處處都透露出大而全的結構設計。如果可以,真的應該細化一下概念設計,比如將音頻采集和音頻播放邏輯分離、音頻輸入和輸出的接口拆分等等,那樣才能談得上結構設計。

2. Chromium對WebRTC的音頻采集適配

根據WebRTC的本地音頻接口設計,Chromium提供了一個WebRtcAudioDeviceImpl類來實現AudioDeviceModule接口,該類對象由PeerConnectionDependencyFactory負責創建和維護,結構如下:

如圖所示,WebRtcAudioDeviceImpl摒棄了原生的AudioDeviceModuleImpl實現中大而全的設計,而是將音頻采集和音頻渲染邏輯分開,分別對應於WebRtcAudioCapturer和WebRtcAudioRenderer。WebRtcAudioRenderer通過WebRtcAudioRendererSource接口的RenderData方法向WebRtcAudioDeviceImpl請求音頻流數據來渲染,WebRtcAudioDeviceImpl將該請求轉發給前面提到的對外交互接口AudioTransport。WebRtcAudioCapturer封裝音頻采集邏輯,它將采集到的數據通過WebRtcLocalAudioTrack對象所持有的PeerConnectionAudioSink接口派發出去,WebRtcAudioDeviceImpl正是實現了該接口來接收音頻采集數據,然后也是通過AudioTransport接口往外傳遞。至於WebRtcAudioCapturer對象的持有者MediaStreamAudioSource和WebMediaStreamTrack,這里暫時有個概念就行,它們是Chromium對HTML5媒體流的實現接口。接下來仔細分析一下WebRtcAudioCapturer和WebRtcAudioRenderer兩個關鍵類,毋庸置疑,它們都涉及到了特定平台實現,而且在Chromium中還跨越了Render和Browser進程。和介紹Chromium視頻采集的模式一樣,由於不是本文重點,這里只列出結構圖,不打算詳解,如果你有開發上的需要,可以照着該結構圖細看源碼。

這是WebRtcAudioCapturer采集音頻數據的結構,牽涉到跨進程通信,結構還是非常復雜的。WebRtcAudioRenderer的結構就不准備介紹了,因為Chromium的這塊設計非常具備對稱性,基本上圖中類命名中的Input改成Output就差不多是WebRtcAudioRenderer的架構了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM