一、概要介紹WebRTC的音頻處理流程,見下圖:
webRTC將音頻會話抽象為一個通道Channel,譬如A與B進行音頻通話,則A需要建立一個Channel與B進行音頻數據傳輸。上圖中有三個Channel,每個Channel包含編解碼和RTP/RTCP發送功能。
以一個Channel而言,應用程序中將包含三個活動線程,錄音線程,音頻接收線程和播放線程。
1)錄音線程:負責麥克風音頻的采集,見圖中紅色路徑,采集到音頻后,緩存到一定長度,進行音頻處理,主要包括EC,AGC和NS等。然后送到Channel,經過音頻
Codec模塊編碼,封裝成RTP包,通過Socket發送出去;
2)接收線程:見藍色路徑,負責接收遠端發送過來的音頻包,解封RTP包,解碼音頻數據,送入NetEQ模塊緩存。
3)播放線程:負責耳機聲音播放,見綠色路徑。播放線程去OutMixer中獲取要播放的音頻數據,首先依次獲取參與會話的Channel中NetEQ存儲的音頻幀,可以對其做AGC和NS處理;然后混合多個Channel的音頻信號,得到混合音頻,傳遞給AudioProcessing模塊進行遠端分析。最后播放出來。
如下為本地回環錄音和播放代碼:
VoiceEngine* ve = VoiceEngine::Create();
VoEBase* base = VoEBase::GetInterface(ve);
base->Init();
int chId = base->CreateChannel();
base->SetSendDestination(chId,3000,"127.0.0.1",4000);
base->SetLocalReceiver(chId,3000,3001,"127.0.0.1");
base->StartPlayout(chId);
base->StartReceive(chId);
base->StartSend(chId);
//....sleep...wait.....
base->StopSend(chId);
base->StopReveive(chId);
base->StopPlayout(chId);
base->Terminate();
本文介紹WebRTC音頻模塊組成和結構,詳細介紹音頻引擎的配置和啟動,相信看完本文后,很多人可以利用WebRTC完成一個音頻通話程序開發。
一、對外接口
音頻部分的對外主要接口如下,各個接口之間的關系如圖1所示。
1)VoiceEngine:負責引擎的所有接口查詢,存儲共享數據信息ShareData。
2)VoEBase:負責音頻處理的基本操作。
3)VoEAudioProcessing:音頻信號處理接口,設置各個音頻處理項的參數。
4)VoECodec:音頻編解碼接口,提供支持的編解碼器查詢,音頻編解碼設置。
5)VoEHardware:音頻硬件設備接口,負責音頻硬件設備的設置。
其它的接口還有VoENetEqStats,VoENetwork,VoERTP_RTCP,VoEVideoSync,VoEVolumeControl,VoEFile,VoECallReport,VoEDtmf,VoEMeidaProcess和VoEEncryption。
WebRTC使用繼承實現接口轉換和查詢,接口之間的數據共享是通過ShareData完成,首先VoiceEngineImpl繼承各個對外接口的實現,所以可以從VoiceEngineImpl很容易獲取其他對外接口。而VoiceEngineImpl本身也繼承ShareData,當從VoiceEngineImpl獲取其他對外接口的同時,隱式的傳遞了ShareData指針,因此各個接口可以很方便的獲取到ShareData的數據信息。因此雖然類與類之間的關系看起來比較混亂,但是使用上比較方便。
利用VoiceEngine獲取對外接口:VoEInterfaceXX* pInterf = VoEInterfaceXX:GetInterface(pVoiceEngine);
二、模塊組成
主要由五大模塊組成:AudioDeviceModule音頻設備模塊,AudioProcess音頻處理模塊,AudioCodingModule音頻編碼模塊,AudioConferenceMixer混音模塊和RtpRtcp傳輸模塊。
ShareData用於粘合各個模塊之間的關系,負責管理全局的對象,包括AudioDeviceModule,TransmitMixer,OutputMixer,ChannelManager和AudioProcess。
錄音流程:AudioDeviceWinCore負責采集音頻數據,傳遞到AudioDeviceBuffer中緩存,AudioDeviceBuffer則將數據送入TransmixMixer,首先交給AudioProcess進行近端音頻處理,完成后分發到各個Channel中,Channel則通過AudioCodingModule進行編碼,編碼后再交付到RtpRtcp中經由RTPSender發送出去。
接收流程:RTPReceiver負責接收音頻RTP包,接收到RTP包后交給Channel,Channel轉交給AudioCodingModule中的ACMNetEQ模塊,進行解碼緩存。
播放流程:Channel從ACMNetEQ模塊中取出緩存的解碼音頻數據,如果需要進行遠端數據處理的話,傳遞給AudioProcess處理。最后所有Channel都匯入到OutputMixer中進行混音,混音后再傳遞到AudioProcess進行遠端音頻分析。最后送入AudioDeviceModule中的AudioDevceWinCore播放。
三、配置
1、音頻引擎創建與刪除
VoiceEngine*pVoeEngine = VoiceEngine::Create();
VoiceEngine::Delete(pVoeEngine);
2、音頻收發
1)音頻通話鏈路創建
WebRTC中的Channel,為一路音頻。作為網絡語音通信,至少要創建一路音頻Channel。
Channel沒有提供對外接口,是有VoEBase來管理的,通過索引號來選定對應的Channel。
VoEBase*base = VoEBase::GetInterface(pVoeEngine);
int ch0 =base->CreateChannel();
2)網絡端口設置
音頻通過RTP和RTCP發送出去,RTP和RTCP使用UDP實現,需要配置網絡端口和地址。
//設置發送給.2機器的3000端口
base->SetSendDestination(ch0,3000,”192.168.8.2”);
//在本機的3000端口接收RTP包
base->SetLocalReceiver(ch0,3000);
3)音頻編碼選擇
VoECodec負責編解碼的配置。
VoECodec*codec = VoEBase::GetInterface(pVoeEngine);
設置Channel的編碼類型之前,要查詢支持的編碼列表。
CodecInstinst;
Intnum = codec->NumOfCodecs();
for(int i=0; i<num; ++i)
{
Codec->GetCodec(I,inst);
//打印編碼信息
}
//設置編碼0
Codec->GetCodec(0,inst);
Codec->SetSendCodec(ch0,inst);
WebRTC自動識別編碼類型,因此解碼不需要設置。
4)啟動
啟動播放:base->StartPlayout(ch0);該操作含義是將通話ch0進行混音輸出。
啟動接收:base->StartReceive(ch0);開始接收后,每增加一路通話,引擎會將音頻進行混音再輸出。
啟動發送:base->StartSend(ch0);啟動發送的時候,會檢查是否正在錄音,如果已經開啟錄音,則不再開啟;否則會執行音頻設備錄音操作。
3、音頻處理的配置
VoEAudioProcessing負責音頻處理的配置。
VoEAudioProcessing*pAudioProc = VoEAudioProcessing::GetInterface(pVoeEngine);
//啟動AGC功能
pAudioProc->SetAgcStatus(true);
4、音頻設備的配置
VoEHardware接口可以查看錄音和播放設備,可以選擇指定的設備進行音頻通話。
VoEHardware*pHardware=VoEAudioProcessing::GetInterface(pVoeEngine);
Int numin =pHardware->GetNumOfRecordingDevices();
For(int i=0;i<numin; ++i)
{
pHardware->GetRecordingDeviceNames(…)
//打印錄音設備
}
//選擇設備0作為錄音設備
pHardware->SetRecordingDevice(0);
播放設備配置類似。