白話解讀 WebRTC 音頻 NetEQ 及優(yōu)化實(shí)踐,webrtc 人聲優(yōu)化-ESG跨境

白話解讀 WebRTC 音頻 NetEQ 及優(yōu)化實(shí)踐,webrtc 人聲優(yōu)化

來源網(wǎng)絡(luò)
來源網(wǎng)絡(luò)
2022-07-05
點(diǎn)贊icon 0
查看icon 800

白話解讀 WebRTC 音頻 NetEQ 及優(yōu)化實(shí)踐,webrtc 人聲優(yōu)化白話解讀 WebRTC 音頻 NetEQ 及優(yōu)化實(shí)踐NetEQ 是 WebRTC 音視頻核心技術(shù)之一,對于提高 VoIP 質(zhì)量有明顯的效果,本文將從更為宏觀的視角,用通俗白話介紹 WebRTC 中音頻 NetEQ 的相關(guān)概念背景和框架原理,以及......

白話解讀 WebRTC 音頻 NetEQ 及優(yōu)化實(shí)踐,webrtc 人聲優(yōu)化




白話解讀 WebRTC 音頻 NetEQ 及優(yōu)化實(shí)踐

NetEQ 是 WebRTC 音視頻核心技術(shù)之一,對于提高 VoIP 質(zhì)量有明顯的效果,本文將從更為宏觀的視角,用通俗白話介紹 WebRTC 中音頻 NetEQ 的相關(guān)概念背景和框架原理,以及相關(guān)的優(yōu)化實(shí)踐。

作者| 良逸審校| 泰一

為什么要 “白話” NetEQ

隨便搜索一下,我們就能在網(wǎng)上找到很多關(guān)于 WebRTC 中音頻 NetEQ 的文章,比如下面的幾篇文章都是非常不錯(cuò)的學(xué)習(xí)資料和參考。特別是西安電子科技大學(xué) 2013 年吳江銳的碩士論文《WebRTC 語音引擎中 NetEQ 技術(shù)的研究》,非常詳盡地介紹了 NetEQ 實(shí)現(xiàn)細(xì)節(jié),也被引用到了很多很多的文章中。

《WebRTC 語音引擎中 NetEQ 技術(shù)的研究》

NetEQ 算法

WebRTC 中音頻相關(guān)的 NetEQ

這些文章大部分從比較 “學(xué)術(shù)” 的或 “算法” 的角度,對 NetEQ 的細(xì)節(jié)做了非常透徹的分析,所以這里我想從更宏觀一些的角度,說一下我個(gè)人的理解。白話更容易被大家接受,爭取一個(gè)數(shù)學(xué)公式都不用,一行代碼都不上就把思路說清楚,有理解不對的地方,還請大家不吝賜教。

丟包、抖動(dòng)和優(yōu)化的理解

在音視頻實(shí)時(shí)通信領(lǐng)域,特別是移動(dòng)辦公(4G),疫情下的居家辦公和在線課堂 (WIFI),網(wǎng)絡(luò)環(huán)境成了影響音視頻質(zhì)量最關(guān)鍵的因素,在差的網(wǎng)絡(luò)質(zhì)量面前,再好的音視頻算法都顯得有些杯水車薪。網(wǎng)絡(luò)質(zhì)量差的表現(xiàn)主要有延時(shí)、亂序、丟包、抖動(dòng),誰能處理和平衡好這幾類問題,誰就能獲得更好的音視頻體驗(yàn)。由于網(wǎng)絡(luò)的基礎(chǔ)延時(shí)是鏈路的選擇決定的,需優(yōu)化鏈路調(diào)度層來解決;而亂序在大部分網(wǎng)絡(luò)條件下并不是很多,而且亂序的程度也不是很嚴(yán)重,所以接下來我們主要會(huì)討論丟包和抖動(dòng)。

抖動(dòng)是數(shù)據(jù)在網(wǎng)絡(luò)上的傳輸忽快忽慢,丟包是數(shù)據(jù)包經(jīng)過網(wǎng)絡(luò)傳輸,因?yàn)楦鞣N原因被丟掉了,經(jīng)過幾次重傳后被成功收到是恢復(fù)包,重傳也失敗的或者恢復(fù)包過時(shí)的,都會(huì)形成真正的丟包,需要丟包恢復(fù) PLC 算法來無中生有的產(chǎn)生一些假數(shù)據(jù)來補(bǔ)償。丟包和抖動(dòng)從時(shí)間維度上又是統(tǒng)一的,等一會(huì)來了的是抖動(dòng),遲到很久才來的是重傳包,等一輩子也不來的就是 “真丟包”,我們的目標(biāo)就是要盡量降低數(shù)據(jù)包變成 “真丟包” 的概率。

優(yōu)化,直觀來講就是某個(gè)數(shù)據(jù)指標(biāo),經(jīng)過一頓猛如虎的操作之后,從 xxx 提升到了 xxx。但我覺得,評判優(yōu)化好壞不能僅僅停留在這個(gè)維度,優(yōu)化是要 “知己知彼”,己是自己的產(chǎn)品需求,彼是現(xiàn)有算法的能力,己彼合一才是最好的優(yōu)化,不管算法是簡單還是復(fù)雜,只要能完美的匹配自己的產(chǎn)品需求,就是最好的算法,“能捉到老鼠的就是好貓”。

NetEQ 及相關(guān)模塊

NetEQ 的出處

《GIPS NetEQ 原始文檔》,這是由 GIPS 公司提供的最原始的 NetEQ 的說明文檔(中文翻譯),里面介紹了什么是 NetEQ 以及對其性能的簡單說明。NetEQ 本質(zhì)上就是一個(gè)音頻的 JitterBuffer(抖動(dòng)緩沖器),名字起的非常貼切,Network Equalizer(網(wǎng)絡(luò)均衡器)。大家都知道 Audio Equalizer 是用來均衡聲音的效果器,而這里的 NetEQ 是用來均衡網(wǎng)絡(luò)抖動(dòng)的效果器。而且 GIPS 還給這個(gè)名字注冊了商標(biāo),所以很多地方看到的是 NetEQ (TM) 。上面的官方文檔中,有一條很重要信息,“最小化抖動(dòng)緩沖帶來的延時(shí)影響”,這說明 NetEQ 的設(shè)計(jì)目標(biāo)之一就是:“追求極低延時(shí)”。這個(gè)信息很關(guān)鍵,為我們后續(xù)的優(yōu)化提供了重要線索。

NetEQ 在音視頻通訊 QoS 流程中的位置

音視頻通訊對于普通用戶來說,只要網(wǎng)絡(luò)是通的,WIFI 和 4G 都可以,一個(gè)呼叫過去,看到人且聽到聲音,就 OK 了,很簡單的事情,但對于底層的實(shí)現(xiàn)卻沒有看起來那么簡單。單 WebRTC 開源引擎的相關(guān)代碼文件數(shù)量就有 20 萬個(gè)左右,代碼行數(shù)不知道有沒有人具體算過,應(yīng)該也是千萬數(shù)量級的了。不知道多少碼農(nóng)為此掉光了頭發(fā) :)。

下面這張圖,是對實(shí)際上更復(fù)雜的音視頻通訊流程的抽象和簡化。左邊是發(fā)快遞 (推流) 側(cè):經(jīng)過采集、編碼、封裝、發(fā)快遞;中間經(jīng)過網(wǎng)絡(luò)傳輸;右邊是接收 (拉流) 側(cè):接收、解包、解碼、播放;這里重點(diǎn)體現(xiàn)了 QoS(Quality of Service,服務(wù)質(zhì)量)的幾個(gè)大的功能,以及跟推拉流數(shù)據(jù)主要流程的關(guān)系。可以看到 QoS 功能分散在音視頻通訊流程中的各個(gè)位置,導(dǎo)致要了解整個(gè)流程之后才能對 QoS 有比較全面的理解。圖上看起來左邊發(fā)快遞側(cè)的 QoS 功能要多一些,這是因?yàn)?QoS 的目的就是要解決通訊過程中的用戶體驗(yàn)問題,要解決問題,最好就是找到問題的源頭,能從源頭解決的,都是比較好的解決方式。但總有一部分問題是不能從源頭來解決的,比如在多人會(huì)議的場景,一個(gè)人的收流側(cè)網(wǎng)絡(luò)壞了,不能影響其它人的開會(huì)體驗(yàn),不能出現(xiàn) “一顆老鼠屎壞掉一鍋粥” 的情況,不能污染源頭。所以收流也要做 QoS 的功能,目前收流側(cè)的必備功能就是 JitterBuffer,包括視頻的和音頻的,本文重點(diǎn)分析音頻的 JitterBuffer NetEQ。

NetEQ 原理及相關(guān)模塊的關(guān)系

上面這張圖是對 NetEQ 及其相關(guān)模塊工作流程的抽象,主要包含 4 個(gè)部分,NetEQ 的輸入、NetEQ 的輸出、音頻重傳 Nack 請求模塊、音視頻同步模塊。為什么要把 Nack 請求模塊和音視頻同步模塊也放進(jìn) NetEQ 的分析中因?yàn)檫@兩個(gè)模塊都直接跟 NetEQ 有依賴,相互影響。圖里面的虛線,標(biāo)識每個(gè)模塊依賴的其它模塊的信息,以及這些信息的來源。接下來介紹一下整個(gè)流程。

1. 首先是 NetEQ 的輸入部分:

底層 Socket 收到一個(gè) UDP 包后,觸發(fā)從 UDP 包到 RTP 包的解析,經(jīng)過對 ***C 和 PayloadType 的匹配,找到對應(yīng)的音頻流接收的 Channel,然后從InsertPacketInternal輸入到 NetEQ 的接收模塊中。

收到的音頻 RTP 包很可能會(huì)帶有 RED 冗余包(redundance),按照 RFC2198 的標(biāo)準(zhǔn)或者一些私有的封裝格式,對其進(jìn)行解包,還原出原始包,重復(fù)的原始包將會(huì)被忽略掉。解出來的原始 RTP 數(shù)據(jù)包會(huì)被按一定的算法插入到 packet buffer 緩存里面去。之后會(huì)將收到的每一個(gè)原始包的序列號,通過UpdateLastReceivedPacket函數(shù)更新到 Nack 重傳請求模塊,Nack 模塊會(huì)通過 RTP 收包或定時(shí)器觸發(fā)兩種模式,調(diào)用GetNackList函數(shù)來生成重傳請求,以 NACK RTCP 包的格式發(fā)快遞給推流側(cè)。

同時(shí),解完的每一個(gè)原始包,得到了時(shí)間軸上唯一的一個(gè)接收時(shí)刻,包和包之間的接收時(shí)間差也能算出來了,這個(gè)接收時(shí)間差除以每個(gè)包的打包時(shí)長就是 NetEQ 內(nèi)部用來做抖動(dòng)估計(jì)的 IAT(interarrival time),比如,兩個(gè)包時(shí)間差是 120ms,而打包時(shí)長是 20ms,則當(dāng)前包的 IAT 值就是 120/20=6。之后每個(gè)包的 IAT 值經(jīng)過核心的網(wǎng)絡(luò)抖動(dòng)估計(jì)模塊(DelayManager)處理之后,得到最終的目標(biāo)水位(TargetLevel),到此 NetEQ 的輸入處理部分就結(jié)束了。

2. 其次是 NetEQ 的輸出部分:

輸出是由音頻硬件播放設(shè)備的播放線程定時(shí)觸發(fā)的,播放設(shè)備會(huì)每 10ms 通過GetAudioInternal接口從 NetEQ 里面取 10ms 長度的數(shù)據(jù)來播放。

進(jìn)入GetAudioInternal的函數(shù)之后,第一步要決策如何應(yīng)對當(dāng)前數(shù)據(jù)請求,這個(gè)任務(wù)交給操作決策模塊來完成,決策模塊根據(jù)之前的和當(dāng)前的數(shù)據(jù)和操作的狀態(tài),給出最終的操作類型判斷。NetEQ 里面定義了幾種操作類型:正常、加速、減速、融合、拉伸(丟包補(bǔ)償)、靜音,這幾種操作的意義,后面再詳細(xì)的說。有了決策的操作類型,再從輸入部分的包緩存(packet buffer)里面取出一個(gè) RTP 包,快遞給抽象的解碼器,抽象的解碼器通過DecodeLoop函數(shù)層層調(diào)用到真正的解碼器進(jìn)行解碼,并把解碼后的 PCM 音頻數(shù)據(jù)放到DecodedBuffer里面去。然后就是開始執(zhí)行不同的操作了,NetEQ 里面為每一種操作都實(shí)現(xiàn)了不同的音頻數(shù)字信號處理算法(DSP),除了 “正?!?操作會(huì)直接使用DecodedBuffer里的解碼數(shù)據(jù),其它操作都會(huì)結(jié)合解碼的數(shù)據(jù)進(jìn)行二次 DSP 處理,處理結(jié)果會(huì)先被放到算法緩存(Algorithm Buffer)里面去,然后再插入到 Sync Buffer 里面。Sync Buffer 是一個(gè)循環(huán) buffer,設(shè)計(jì)的比較巧妙,存放了已經(jīng)播放過的數(shù)據(jù)、解碼后未播放的數(shù)據(jù),剛剛從算法緩存里插入的數(shù)據(jù)放在 Sync Buffer 的末尾,如上圖所示。最后就是從 Sync Buffer 取出最早解碼后的數(shù)據(jù),快遞出去給外部的混音模塊,混音之后再國際快遞音頻硬件來播放。

另外,從圖上可以看出決策模塊(BufferLevelFilter)會(huì)結(jié)合當(dāng)前包緩存 packet buffer 里緩存的時(shí)長,和 Sync Buffer 里緩存的數(shù)據(jù)時(shí)長,經(jīng)過算法過濾后得到音頻當(dāng)前的緩存水位。音視頻同步模塊會(huì)使用當(dāng)前音頻緩存水位,和視頻當(dāng)前緩存水位,結(jié)合最新 RTP 包的時(shí)間戳和音視頻的 SR 包獲得的時(shí)間戳,計(jì)算出音視頻的不同步程度,再通過 SetMinimumPlayoutDelay 最終設(shè)置到 NetEQ 里面的最小目標(biāo)水位,來控制 TargetLevel,實(shí)現(xiàn)音視頻同步。

NetEQ 內(nèi)部模塊

NetEQ 抖動(dòng)估計(jì)模塊(DelayManager)

1. 平穩(wěn)抖動(dòng)估計(jì)部分:

將每個(gè)包的 IAT 值,按照一定的比例(取多少比例是由下面的遺忘因子部分的計(jì)算決定的),累加到下面的 IAT 統(tǒng)計(jì)的直方圖里面,最后計(jì)算從左往右累加值的 0.95 位置,此位置的 IAT 值作為最后的抖動(dòng) IAT 估計(jì)值。例如下圖,假定目標(biāo)水位 TargetLevel 是 9,意味著目標(biāo)緩存數(shù)據(jù)時(shí)長將會(huì)是 180ms(假定打包時(shí)長 20ms)。

2. 平穩(wěn)抖動(dòng)遺忘因子計(jì)算:

遺忘因子是用來控制當(dāng)前包的 IAT 值取多少比例累加到上面的直方圖里面去的系數(shù),計(jì)算過程用了一個(gè)看起來比較復(fù)雜的公式,經(jīng)過分析,其本質(zhì)就是下面的黃色曲線,意思是開始的時(shí)候遺忘因子小,會(huì)取更多的當(dāng)前包的 IAT 值來累加,隨著時(shí)間推移,遺忘因子逐漸變大,會(huì)取更少的當(dāng)前包 IAT 值來累加。這個(gè)過程搞的有點(diǎn)復(fù)雜,從工程角度看完全可以簡化成直線之類的,因?yàn)闇y試下來 5s 左右的時(shí)間,基本就收斂到目標(biāo)值 0.9993 了,其實(shí)這個(gè) 0.9993 才是影響抖動(dòng)估計(jì)的最主要的因素,很多優(yōu)化也是直接修改這個(gè)系數(shù)來調(diào)節(jié)估計(jì)的靈敏度。

3. 峰值抖動(dòng)估計(jì):

DelayManager 中有一個(gè)峰值檢測器 PeakDetector 用來識別峰值,如果頻繁檢測到峰值,會(huì)進(jìn)入峰值抖動(dòng)的估計(jì)狀態(tài),取最大的峰值作為最終估計(jì)結(jié)果,而且一旦進(jìn)入這個(gè)狀態(tài)會(huì)一直維持 20s 時(shí)間,不管當(dāng)前抖動(dòng)是否已經(jīng)恢復(fù)正常了。下面是一個(gè)示意圖。

NetEQ 操作決策模塊(DecisionLogic)

決策模塊的簡化后的基本判定邏輯,如下圖所示,比較簡潔不用解釋。這里解釋一下下面這幾個(gè)操作類型的意義:

ComfortNoise:是用來產(chǎn)生舒適噪聲的,比單純的靜音包聽起來會(huì)更舒服的靜音狀態(tài);

Expand(PLC):丟包補(bǔ)償,最重要的無中生有算法模塊,解決 “真丟包” 時(shí)沒數(shù)據(jù)的問題,造假專業(yè)戶 ;

Merge:如果上一次是 Expand 造假出來的數(shù)據(jù),那為了聽起來更舒服一些,會(huì)跟正常數(shù)據(jù)包做一次融合算法;

Accelerate:變聲不變調(diào)的加速播放算法;

PreemptiveExpand:變聲不變調(diào)的減速播放算法;

Normal:正常的解碼播放,不額外引入假數(shù)據(jù);

NetEQ 相關(guān)模塊優(yōu)化點(diǎn)

NetEQ 抗抖動(dòng)優(yōu)化

由于 NetEQ 的設(shè)計(jì)目標(biāo)是 “極低延時(shí)”,不能很好的匹配,視頻會(huì)議,在線課堂,直播連麥等非極低延時(shí)場景,需要對其敏感度進(jìn)行調(diào)整,主要調(diào)整抖動(dòng)估計(jì)模塊相關(guān)的靈敏度;

直播場景,由于對于延時(shí)敏感度可以到秒級以上,所以需要啟用 StreamMode 的功能(新版本中好像去掉了),而且也需要對其中參數(shù)進(jìn)行適配;

服務(wù)于極低延時(shí)目標(biāo),原始的包緩存 packetbuffer 太小,容易造成 flush,需要按業(yè)務(wù)需要調(diào)大一些;

還有一些業(yè)務(wù)會(huì)根據(jù)自己的業(yè)務(wù)場景主動(dòng)識別網(wǎng)絡(luò)狀況,然后直接設(shè)置最小 TargetLevel,簡單粗暴的控制 NetEQ 的水位。

NetEQ 抗丟包優(yōu)化:

原始的 WebRTC 的 Nack 丟包請求的觸發(fā)機(jī)制是用包觸發(fā)的,在弱網(wǎng)下會(huì)惡化重傳效果,可以改為定時(shí)觸發(fā)來解決;

丟包場景會(huì)有重傳,但如果 buffer 太小,重傳也會(huì)被丟棄,所以為了提高重傳效率,增加 ARQ 延時(shí)預(yù)留功能,可明顯降低拉伸率;

比較算法級的優(yōu)化是對丟包補(bǔ)償 PLC 算法的優(yōu)化,調(diào)整現(xiàn)有 NetEQ 的拉伸機(jī)制,優(yōu)化聽感效果;

開啟 Opus 的 Dtx 功能之后,在丟包場景會(huì)導(dǎo)致音頻 Buffer 變大,需要單獨(dú)優(yōu)化 Dtx 相關(guān)處理邏輯。

下面是 ARQ 延時(shí)預(yù)留功能開啟后的效果對比,平均拉伸率降低 50%,延時(shí)也會(huì)相應(yīng)增加:

音視頻同步優(yōu)化:

原始的 WebRTC 的 P2P 音視頻同步算法是沒有問題的,但是目前架構(gòu)上面一般都有媒體轉(zhuǎn)發(fā)服務(wù)器(SFU),而服務(wù)器的 SR 包生成算法可能會(huì)由于某些限制或者錯(cuò)誤會(huì)不完全正確,導(dǎo)致無法正常同步,為規(guī)避 SR 包生成錯(cuò)誤,需要優(yōu)化音視頻同步模塊的計(jì)算方式,使用水位為主要參考來同步,即在接收端保證音視頻的緩存時(shí)間是差不多大小的。下面是優(yōu)化效果的對比:

還有一種音視頻同步的問題,其實(shí)不是音視頻同步機(jī)制導(dǎo)致的,而是設(shè)備性能有問題,不能及時(shí)處理視頻的解碼和渲染,導(dǎo)致視頻數(shù)據(jù)累積,從而形成的音視頻不同步。這種問題可以通過對比不同步時(shí)長的趨勢,跟視頻解碼和渲染時(shí)長的趨勢,兩者匹配度會(huì)很高,如下圖所示:

總結(jié)

NetEQ 作為音頻接收側(cè)的核心功能,基本上包含了各個(gè)方面,所以很多很多音視頻通訊的技術(shù)實(shí)現(xiàn)里都會(huì)有它的蹤跡,乘著 WebRTC 開源快 10 年的東風(fēng),NetEQ 也變的非常普及,希望這篇白話文章能幫大家更好的理解 NetEQ。

作者最后的話:需求不停歇,優(yōu)化無止境


文章推薦
YouTube油管賺錢,youtube賺錢模式
TikTok運(yùn)營分享——起號和剪輯技巧,tiktok怎么檢測賬號異常
Yandex.Metrica的三種主要營銷工具,yandex屬于主要的sem營銷渠道
阿里云ecs如何處理CentOS DNS 解析超時(shí),阿里云服務(wù)器ecs怎么選


特別聲明:以上文章內(nèi)容僅代表作者本人觀點(diǎn),不代表ESG跨境電商觀點(diǎn)或立場。如有關(guān)于作品內(nèi)容、版權(quán)或其它問題請于作品發(fā)表后的30日內(nèi)與ESG跨境電商聯(lián)系。

搜索 放大鏡
韓國平臺交流群
加入
韓國平臺交流群
掃碼進(jìn)群
歐洲多平臺交流群
加入
歐洲多平臺交流群
掃碼進(jìn)群
美國賣家交流群
加入
美國賣家交流群
掃碼進(jìn)群
ESG跨境專屬福利分享群
加入
ESG跨境專屬福利分享群
掃碼進(jìn)群
拉美電商交流群
加入
拉美電商交流群
掃碼進(jìn)群
亞馬遜跨境增長交流群
加入
亞馬遜跨境增長交流群
掃碼進(jìn)群
亞馬遜跨境增長交流群
加入
亞馬遜跨境增長交流群
掃碼進(jìn)群
拉美電商交流群
加入
拉美電商交流群
掃碼進(jìn)群
ESG獨(dú)家招商-PHH GROUP賣家交流群
加入
ESG獨(dú)家招商-PHH GROUP賣家交流群
掃碼進(jìn)群
《TikTok官方運(yùn)營干貨合集》
《TikTok綜合運(yùn)營手冊》
《TikTok短視頻運(yùn)營手冊》
《TikTok直播運(yùn)營手冊》
《TikTok全球趨勢報(bào)告》
《韓國節(jié)日營銷指南》
《開店大全-全球合集》
《開店大全-主流平臺篇》
《開店大全-東南亞篇》
《CD平臺自注冊指南》
通過ESG入駐平臺,您將解鎖
綠色通道,更高的入駐成功率
專業(yè)1v1客戶經(jīng)理服務(wù)
運(yùn)營實(shí)操指導(dǎo)
運(yùn)營提效資源福利
平臺官方專屬優(yōu)惠

立即登記,定期獲得更多資訊

訂閱
聯(lián)系顧問

平臺顧問

平臺顧問 平臺顧問

微信掃一掃
馬上聯(lián)系在線顧問

icon icon

小程序

微信小程序

ESG跨境小程序
手機(jī)入駐更便捷

icon icon

返回頂部

【免費(fèi)領(lǐng)取】全球跨境電商運(yùn)營干貨 關(guān)閉