教育場景下的實時音訊解決方案
本文來自網易雲信 資深音訊演算法工程師 李備在LiveVideoStackCon 2018講師熱身分享,並由LiveVideoStack整理而成。在分享中李備詳細分析了線上教育的音訊需求,以及一般軟體音訊框架,和行業的挑戰。
文 / 李備
整理 / LiveVideoStack
直播回放:
https://www.baijiayun.com/web/playback/index?classid=18100937220683&session_id=201810110&token=qJU73GZ_Sypg5tXwrQlPW-dYf81fngNF6RfMSjQA80ffLA0n-BEkqaRIbUQmUGIKXn3EFapSbJeMCTpCPak4Cg
大家好,我是來自網易雲信的李備,今天我將與大家一起探究教育場景下的實時音訊解決方案。
本次分享將圍繞以下幾部分進行:
1. 實時音視訊的市場需求
1.1 市場觀察
隨著我國網際網路行業的蓬勃發展與寬頻水平的提升,消費者早已不滿足於通過簡單的文字圖片瀏覽新聞,而是期待通過更佳生動精彩的音視訊獲取知識瞭解世界。根據網易雲信平臺觀測的資料,音視訊社交應用時長在近兩年呈現飛速增長,隨之增長的同樣還有中國線上教育市場交易規模,從2010年至2017年增長近10倍,並預計在2018~2019年保持增長。可以說,實時音視訊技術助力眾多產業轉型升級,並使得視訊會議等經典應用場景重獲新生。眾多的新興場景與行業藉助實時音視訊技術實現了更佳豐富炫目高效準確的場景表達與業務落地,同時也進一步促進了實時音視訊的技術演進與行業探索。實時音視訊正在各個千億、百億市場快速發展並逐漸成為基礎設施型重要技術。
1.2 應用場景
我們的音視訊行業主要存在以下應用場景:以網易公開課為代表的點播,以Finger為代表的直播,以網易雲課堂為代表的互動直播與以各種P2P、小班教學、大型培訓為代表的實時音視訊。
1.3 直播/點播框架
下圖展示的是直播與點播的技術框架。
而與上述直播/點播框架不同的是,互動直播框架更加強調音視訊的實時性與強互動性。來自Web 端連麥觀眾的音訊資料會通過WebRTC閘道器傳輸至實時音視訊中轉伺服器,並在此與來自手機連麥觀眾和PC端主播的音視訊資料一起由實時音視訊中轉伺服器轉發至互動直播伺服器。互動直播伺服器會對這些資料做合成/推流處理,傳輸至融合CDN流媒體伺服器,由流媒體伺服器推送資料給觀看互動直播的普通觀眾。與此同時,實時音視訊中轉伺服器同樣負責手機連麥觀眾與PC端主播的直播互動資料交換,從而實現互動直播的效果。
2. 軟體層實時音訊解決方案
2.1 實時音框架的執行緒模型與資料驅動方式
上圖展示的是實時音訊的簡單框架執行緒模型,這裡需要提醒的是,其中的解碼主要由客戶端完成,實時音的服務端不參加解碼而是把來自各端的資料包篩選之後傳遞給其他端。我們以音樂教學場景為例,學生與老師正在上課,此時來自學生的音訊訊號被其移動終端採集模組採集,經過混音消除、降噪、自動增益控制等音訊的前處理過程,由音訊編碼器進行編碼。這裡的編碼器主要分為專屬語音編碼器與音樂編碼器。音訊資料經過編碼器的編碼處理後會被髮送至網路,此時接收端會收到一個緩衝抵抗網路抖動的Jitter Buffer。解碼後的音訊資料經過快慢速調製與TSM後進行後處理,最後播放。播放時產生的回聲會被捕捉並重覆上述流程。
在硬體層面,終端製造商對音訊處理流程中所需要的硬體都有一套同一切完善的引數調整經驗,例如麥克風的採集幀率、拾音距離、回聲延遲等都有統一規範;而考慮軟體層面的實時音訊則需面臨裝置數量龐大的難題,我們需要統一海量裝置與不同平臺的複雜資料輸入並且考慮到軟體層面的不可預知性,也就是我們需要一個完善的音訊處理系統,優化各模組之間的協同工作並保證演算法的穩定性。因此在這裡我向大家展示一下WebRTC執行緒模型的設計和資料驅動方式:不同的顏色代表不同的執行緒。首先,音訊資料被採集模組採集後進行音訊前處理,之後經由交付Buffer被交至音訊Codec進行編碼。(這裡強調的是,我們不把音訊Buffer和Codec放在一個執行緒的原因是音訊Codec的實時性計算量要求較高,需要單獨的一個執行緒執行。而經過網路傳送時一般網路執行緒是直接將資料傳輸至Audio Jitter Buff-er,Audio Jitter Buffer獲取資料後會在網路執行緒上接收資料包,並更新網路統計和策略,而playback的callback請求往上回調至Audio Jitter Buffer請求資料過程是執行在Playback的Callback執行緒上。經過解碼後音訊資料會進行TSM、MIX等(如果是處理多路MIX,有些廠家可能會使音訊解碼單獨在一個執行緒上執行,這一點視應用場景而定,如果是處理一路MIX則可以簡單地執行在播放執行緒上。)關於其中的驅動方式,一些開發者喜歡使用Timer機制驅動資料,但這在實時音訊框架中並不推薦。以Audio三維演算法處理為例,音訊每一幀處理需要大約10毫秒的時間,對時間的精度要求很高;而簡單的Timer驅動無法滿足這種高精度,尤其是在複雜的系統中很容易出現延遲,這為整個音訊處理系統帶來的影響無疑是毀滅性的。因此我們一般採取將驅動執行在系統(回撥)中的解決方案,因為系統(回撥)的高優先順序可確保整個系統的穩定執行。Google就曾經在I/O大會上面推薦把audio process放到系統的採集播放執行緒裡 ;右側展示的主要有兩個系統:收包網路系統與底層的用來驅動音訊解碼、後處理、MIX的Playback。一個音訊引擎框架的穩定性直接決定了其輸出聲音的質量與實時性。
2.2 音訊前處理框架
捕捉到的音訊資料會進入Audio 3A處理。其中Audio 3A由AEC、ANS、AGC組成。不同的應用場景三者的處理順序也不同,如在WebRTC中音訊資料回依次經過AEC和NS 或者 NS 與AECM(AECM 是WebRTC專門為移動端打造的演算法,計算量低,而AEC 是為PC打造的)。而在AEC(回聲消除演算法),為什麼需要這個演算法呢?當一個裝置在播放聲音經過空間中的多次反射會被麥克風再次捕捉並採集到系統當中,這時音訊的輸入既有空間反射的回聲也有本端說話聲,如果缺少此模組就意味著通話中說話人一直可以聽到自己的聲音回來,這是非常差的一種體驗,這當然是需要我們避免的。這裡AEC的作用就是通過播放的參考訊號跟蹤出回聲並從採集訊號中把回聲消除掉,隨後再經過降噪處理去除噪聲。而其中的AECM是在NS模組之後通過獲取clean與noise資料進行分析,AEC則是NS模組之前直接獲取noise資料進行分析。音訊資料完成AEC與NS的處理後會進行AGC處理,其包括AAGC(模擬域的自動增益控制)與DAGC(數字域的自動增益控制)。其中AAGC的主要作用是通過系統的採集音量設定介面調整輸入訊號(大多用於PC端,移動端一般沒有輸入音量的系統介面),如藉助Windows上的的API調整採集音量等引數。AAGC可為輸入的音訊資料帶來明顯的質量優化,如提高信噪比,避免輸入訊號溢位等。但由於我們服務的跨平臺要求,我們需要構建一個面向多平臺裝置的框架,在不同的輸入平臺和裝置都會有不同的輸入音量,DAGC可以根據對輸入訊號的跟蹤,儘量的調整訊號到達期望大小(幅值或能量),從而避免不同裝置採集帶來的音量差異過大。完成AGC處理的音訊資料,即可進入Audio Encode進行編碼操作。
這裡我想特別介紹一下Audio Jitter Buffer,由於視訊的傳送位元速率較高容易對網路造成較大沖擊比較大,而音訊在窄帶與中等位元速率的情景下的傳送位元速率在50KBPS上下,不會為網路帶來較大壓力,很多廠家在做音訊QOS的時候並不會控制傳送頻寬(因為寬頻的音訊頻寬不高,對於網路擁塞貢獻不大),而把重點工作都放在接收端的jitter buffer策略上。但我們的人耳對連續性非常敏感,一旦有包沒能及時傳遞出現丟包,那麼觀眾就可體驗到瞬間的卡頓,這種頻繁的卡頓會讓使用者體驗大打折扣。因此我們需要一個抵抗抖動的Buffer來抵抗網路抖動的衝擊,從對Delay要求高、平滑穩定過渡的角度考慮我們希望選擇較長的Buffer,而從實時性出發我們又希望儘可能縮短buffer。為了平衡網路抖動與實時性,我們引入Audio Jitter Buffer進行處理。一般用來在接收端控制網路抖動,而在不同模式下采取的抗抖動方案也不盡相同。Jitter Buffer框架與其包含的模組展示在這張圖中,其中黃色代表網路執行緒。Audio Play Callback的資料首先傳輸至Manager,同時上傳一些必要資訊,此時音訊資料會經過Jitter Policy處理傳輸至Audio Decode並在播放端觸發callback,再由Callback驅動整個抓包流程。JitterBuffer請求包時會根據Jitter Policy進行音訊解碼或PLC/CNG、Slience等。最後經過後處理與MIX的反覆處理,資料被傳輸至Audio Play Callback。不同廠商的Jitter Policy處理方案也不一樣,如較為出名的WebRTC NeTEQ演算法,其中集成了自適應抖動控制演算法以及語音包丟失隱藏演算法。除此之外, JitterBuffer在跟蹤預測準每一個包的jitter的時候,也需要考慮實際的快取播放策略,比如三個包的jitter 分別是100ms,50ms和150ms,如果每次都緊跟預測的jitter,當第一個包來的時候需要快取100ms,然後第二個包來的時候發現只需要快取50ms,實際快取多了需要TSM 調整,直到第三個包來,發現要快取的又要變化了,又需要需要TSM 調整,那麼這樣最後的效果將是非常糟糕的。JitterBuffer的目標就是快取適合的資料可以抵抗網路jitter的抖動,自適應既要兼顧考慮時延,又不能變化過於頻繁破壞聲音體驗,也不能不跟不上網路變化造成快取不足造成丟包。
2.3 Active Speaker List
Active Speaker List(下文簡稱ASL)主要被用於解決大型會議的一些痛點。我們知道,實時音伺服器一般不做伺服器端解碼,如果伺服器解碼會導致伺服器計算量增加;隨著Client的增多與業務的拓展,加之分發到Client的功能與操作越來越多,伺服器的壓力會越來越大直到威脅整個服務的正常執行;為了確保伺服器有著更好的併發的能力與擴充套件性,可將此解碼工作轉移至Client端實現並且允許Jitter Buffer監控整條鏈路及時調整策略。如果在大型的會議裡,如千人會議裡面,每一路的音訊下行都接近一千路,光是純音訊的頻寬就非常高了。由於人的聽覺最多可同時拾取三路聲音並獲取其中資訊,而多人開會最多的情景是一個或幾個人主講剩下的人聆聽,因此我們需要ASL在伺服器上選擇說話的線路並將線路上的音訊資料傳給其他所有參與者,如果面對幾百上千人同時講話,ASL則會選取音量最高或者講話內容最清晰的進行推送,這可極大方便大型視訊會議的順利開展。
3. 行業痛點
音訊行業之痛主要是複雜的網路對音訊的衝擊與碎片化的終端裝置背後差距懸殊的硬體。尤其是對Android平臺而言,軟體層面不同廠家定製系統的處理流程、硬體層面手機的工業設計、處理器、感測器等都不相同,難以用統一的平臺解決方案處理這些裝置的音視訊問題,主要體現在演算法的挑戰難度上;與此同時,我們希望演算法魯棒性更強,這就意味著需要考慮更多的案例,而演算法不可能考慮到所有的案例,我們必須根據實際情況進行相應取捨……這些都是在未來亟待解決的行業痛點。
精品文章推薦
線上分享:
技術乾貨: