从0到1 构建实时音视频引擎
最近幾年,實時音視頻領域越來越熱,今年的疫情更是“火上澆油”了一把。網易智企旗下產品網易云信在實時音視頻領域深耕多年,積累了不少實踐經驗。在本文里,筆者將以烹飪?yōu)楸扔?#xff0c;深入淺出地將網易云信如何從0到1構建實時音視頻引擎的過程分享給讀者。
跟業(yè)界很多引擎的實現方案一樣,網易云信也是基于WebRTC構建的實時音視頻引擎。本文會從介紹WebRTC提供了什么開始,一步步引入工程化/產品化/優(yōu)化實踐等內容,完整呈現引擎的整個構建過程。
首先,WebRTC是什么?
WebRTC全稱Web Real-Time Communication。原本是用于支持網頁瀏覽器開發(fā)實時音視頻用的一套API,它提供了統(tǒng)一的交互協(xié)議:SDP,同時提供了視頻會議的核心技術,包括音頻引擎、視頻引擎、傳輸控制三大塊,并且還支持跨平臺:Windows / Mac / Linux / Android / iOS。
WebRTC本來就是給瀏覽器用的,沒有native代碼可以參考。但是,在2011年它被Google開源了,源碼被應用于各種native開發(fā),并被業(yè)內廣泛借鑒,大有一統(tǒng)天下的趨勢。
有了WebRTC,是不是就等于有了實時音視頻引擎呢?并不是,以烹飪來做比喻的話,有了WebRTC就好比是有了廚具/原材料,而實時音視頻引擎是給客戶的那頓大餐。
?
有了廚具/原材料,第一步是什么呢?“學會廚具使用方法”—WebRTC的源碼工程化。
WebRTC 官網和其他第三方渠道已有不少資料介紹如何使用Google 提供的工具編譯出WebRTC的生成物,本文不再詳細贅述。
會用廚具之后,是不是就能做出一頓好吃的飯菜了呢?
現實往往是這樣的:用著很牛的廚具和材料,做著難以下咽的料理…
?
所以要以合理的步驟來做一頓飯菜,這飯菜才適合下咽。在網易云信的實踐中,我們選擇了怎樣的步驟呢?因為基于WebRTC建立通話的基礎是通過設置SDP來完成的,所以我們選擇了通過信令傳遞SDP信息,然后設置SDP信息給PeerConnection來完成建聯。整個多人音視頻能力中核心的是發(fā)布、訂閱、響應訂閱等媒體功能,其他的功能都是圍繞著這些核心功能來做的。而核心功能是采用如下流程來完成的:
舉例:
發(fā)布音視頻:把自己的SDP信息給媒體服務器(上圖中的媒體服務器是SFU服務器),媒體服務器把自己對應的SDP信息返回來。這樣就具備了Local SDP 和 Remote SDP,就可以完成一次設置并建聯了。
訂閱和被訂閱也是類似的過程,通過發(fā)送自己的SDP給服務器,拿到遠端的SDP信息,然后建立/更新聯接。
以上是一個基本的建聯過程。拿烹飪來說,是不是飯菜做熟了就很好吃了呢?其實還有很多需要提升的:把飯菜做得更好吃/根據不同人的口味做不同的飯菜。這個提升的過程,就是各種優(yōu)化。
網易云信的優(yōu)化實踐有很多,下面介紹其中的幾種優(yōu)化。
?
優(yōu)化一:Simulcast
所謂Simulcast,就是在一路視頻里提供多個分辨率的視頻流,訂閱方靈活根據需要訂閱想要的視頻流。典型的就是在會議場景的應用,如下圖:
如果沒有Simulcast功能,假定需要720P的視頻,在這個場景里,發(fā)送方需要發(fā)送/壓碼一路720P視頻,接收/解碼4路720P視頻,帶寬和性能壓力非常大。如果增加了Simulcast能力,同時能夠發(fā)送720P/180P的視頻。在這個場景里,發(fā)送方通常只要發(fā)送/壓碼180P視頻,接收/解碼1路720P視頻,接收/解碼3路180P視頻。帶寬要求和性能要求降到了原先的1/4左右,而效果是完全一樣的。
WebRTC的Simulcast功能,并不是由WebRTC團隊完成的,而是一個第三方開發(fā)團隊開發(fā),并merge到WebRTC里去的。要開啟它,需要開啟一個實驗室接口,然后在Video quality control里更改相應的源碼才能正常運行。配合上層的信令,就能做到靈活訂閱了。
?
優(yōu)化二:視頻硬件編解碼
通常,視頻硬件編解碼會比軟件編解碼性能開銷更低。無論在日常使用還是上高清分辨率(比如1080P)都有很重要的作用。WebRTC的硬件編解碼功能不夠完整,為了能用起來,我們在整條路徑中做了不少事情。如下圖:
Android端主要是硬件的碎片化引起,iOS端主要是偶發(fā)的崩潰引起。碎片化靠下發(fā)白名單來解決(只對認證過的硬件啟用),偶發(fā)崩潰靠收集線上信息來限制特定版本/特定機型來解決。兩個移動端都有偶發(fā)失敗的問題,所以設計了一個失敗時的回退機制,以免視頻卡住的現象發(fā)生。最后再補完simulcast邏輯,就完成了這個硬件編解碼的支持。
以上的優(yōu)化,基本上是大部分場景都可以適用的,但也有些優(yōu)化要看具體場景確定。這就好比不同的人口味不一樣,有人喜歡辣,有人喜歡原味,做不到一套方法搞定所有的食客,于是我們做了定制化的優(yōu)化來進行適應。
?
優(yōu)化三:Audio profile
Audio 的優(yōu)化做了很多,這其中挑了一個 Audio profile 的優(yōu)化來講。語音場景里,需要的編碼碼率不太高,而娛樂場景里(比如播放伴音歌曲的),對碼率要求就高很多了,不然會丟失音質。碼率要求高了對網絡要求也會高,所以為了應對不同的場景,audio 的采樣數/聲道數都是不一樣的。音頻硬件又是五花八門,能力不統(tǒng)一,如果采集上來的數據不合適,就需要做重采樣支持。同時codec的傾向也做了speech 和 music 的區(qū)分,以適應不同的需要。WebRTC原先的設計里,基本只考慮了語音,跟娛樂場景相關的部分都需要優(yōu)化支持。同時,為了能夠兼容更多的音頻處理/更差性能的機器,我們在優(yōu)化過程中,將播放/采集線程進行了分離,相當于硬件要求降低了一半。
?
優(yōu)化四:傳輸策略優(yōu)化
傳輸策略要照顧實時性/清晰度/流暢度三個維度,理想中的優(yōu)化當然是三個都做得更好,可惜這三個維度是互為掣肘的。如下圖所示:
這三個點里,一個點加強了,其他點會被影響。舉個例子:實時性要求很高,那緩存時間就得降低,這時候如果出現網絡抖動,很可能會卡頓,流暢性就受影響。所以想要同一個策略滿足不同的需求不太現實。在項目實踐中,我們根據不同的場景,設置不同的策略,來滿足不同傾向的需求。
通信場景一般對實時性要求高。舉個例子,你跟別人語音聊天,隔了一秒鐘才聽見對面的聲音,那么兩個人的聊天很容易“打架”,互相搶著發(fā)言。如果是多人語音聊天,那這個現象就更加嚴重了。娛樂直播場景對清晰度要求很高,但卻可以接受較高的延時。所以我們在實踐過程中給予了不同的策略支持,就好比做不同口味的飯菜來滿足不同人的口味。
?
以上就是網易云信在構建音視頻引擎過程中的一些實踐經驗,在此分享給大家,希望能給有興趣的同學參考。
總結
以上是生活随笔為你收集整理的从0到1 构建实时音视频引擎的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网易云信亮相LiveVideoStack
- 下一篇: 云信小课堂|如何实现音视频通话