從 0 到 1 構建實時音視頻引擎

最近幾年,實時音視頻領域愈來愈熱,今年的疫情更是「火上澆油」了一把。網易智企旗下產品網易雲信在實時音視頻領域深耕多年,積累了很多實踐經驗。在本文裏,筆者將以烹飪爲比喻,深刻淺出地將網易雲信如何從0到1構建實時音視頻引擎的過程分享給讀者。瀏覽器

跟業界不少引擎的實現方案同樣,網易雲信也是基於 WebRTC 構建的實時音視頻引擎。本文會從介紹 WebRTC 提供了什麼開始,一步步引入工程化/產品化/優化實踐等內容,完整呈現引擎的整個構建過程。緩存

WebRTC 是什麼

首先,WebRTC 是什麼?服務器

WebRTC 全稱 Web Real-Time Communication。本來是用於支持網頁瀏覽器開發實時音視頻用的一套 API,它提供了統一的交互協議:SDP,同時提供了視頻會議的核心技術,包括音頻引擎、視頻引擎、傳輸控制三大塊,而且還支持跨平臺:Windows / Mac / Linux / Android / iOS。網絡

WebRTC 原本就是給瀏覽器用的,沒有 native 代碼能夠參考。可是,在 2011 年它被 Google 開源了,源碼被應用於各類 native 開發,並被業內普遍借鑑,大有一統天下的趨勢。ide

WebRTC 提供了什麼?

有了 WebRTC,是否是就等於有了實時音視頻引擎呢?並非,以烹飪來作比喻的話,有了 WebRTC 就比如是有了廚具/原材料,而實時音視頻引擎是給客戶的那頓大餐。工具

圖1.png

有了廚具/原材料,第一步是什麼呢?「學會廚具使用方法」— WebRTC 的源碼工程化。性能

WebRTC 官網和其餘第三方渠道已有很多資料介紹如何使用 Google 提供的工具編譯出 WebRTC 的生成物,本文再也不詳細贅述。優化

會用廚具以後,是否是就能作出一頓好吃的飯菜了呢?編碼

現實每每是這樣的:用着很牛的廚具和材料,作着難如下嚥的料理…線程

圖2.png

因此要以合理的步驟來作一頓飯菜,這飯菜才適合下嚥。

基於 WebRTC 網易雲信如何構建音視頻能力

在網易雲信的實踐中,咱們選擇了怎樣的步驟呢?由於基於 WebRTC 創建通話的基礎是經過設置 SDP 來完成的,因此咱們選擇了經過信令傳遞 SDP 信息,而後設置 SDP 信息給 PeerConnection 來完成建聯。整個多人音視頻能力中核心的是發佈、訂閱、響應訂閱等媒體功能,其餘的功能都是圍繞着這些核心功能來作的。而核心功能是採用以下流程來完成的:

圖3.png

舉例:

發佈音視頻:把本身的 SDP 信息給媒體服務器(上圖中的媒體服務器是 SFU 服務器),媒體服務器把本身對應的 SDP 信息返回來。這樣就具有了 Local SDP 和 Remote SDP,就能夠完成一次設置並建聯了。

訂閱和被訂閱也是相似的過程,經過發送本身的 SDP 給服務器,拿到遠端的 SDP 信息,而後創建/更新聯接。

以上是一個基本的建聯過程。拿烹飪來講,是否是飯菜作熟了就很好吃了呢?其實還有不少須要提高的:把飯菜作得更好吃/根據不一樣人的口味作不一樣的飯菜。這個提高的過程,就是各類優化。

網易雲信優化實踐

網易雲信的優化實踐有不少,下面介紹其中的幾種優化。

優化一:Simulcast

所謂 Simulcast,就是在一路視頻裏提供多個分辨率的視頻流,訂閱方靈活根據須要訂閱想要的視頻流。典型的就是在會議場景的應用,以下圖:

圖4.png

若是沒有 Simulcast 功能,假定須要 720P 的視頻,在這個場景裏,發送方須要發送/壓碼一路 720P 視頻,接收/解碼4路 720P 視頻,帶寬和性能壓力很是大。若是增長了 Simulcast 能力,同時可以發送 720P/180P 的視頻。在這個場景裏,發送方一般只要發送/壓碼 180P 視頻,接收/解碼1路 720P 視頻,接收/解碼3路 180P 視頻。帶寬要求和性能要求降到了原先的1/4左右,而效果是徹底同樣的。

WebRTC 的 Simulcast 功能,並非由 WebRTC 團隊完成的,而是一個第三方開發團隊開發,並 merge 到 WebRTC 裏去的。要開啓它,須要開啓一個實驗室接口,而後在 Video quality control 裏更改相應的源碼才能正常運行。配合上層的信令,就能作到靈活訂閱了。

優化二:視頻硬件編解碼

一般,視頻硬件編解碼會比軟件編解碼性能開銷更低。不管在平常使用仍是上高清分辨率(好比 1080P)都有很重要的做用。WebRTC 的硬件編解碼功能不夠完整,爲了能用起來,咱們在整條路徑中作了很多事情。以下圖:

圖5.png

Android 端主要是硬件的碎片化引發,iOS 端主要是偶發的崩潰引發。碎片化靠下發白名單來解決(只對認證過的硬件啓用),偶發崩潰靠收集線上信息來限制特定版本/特定機型來解決。兩個移動端都有偶發失敗的問題,因此設計了一個失敗時的回退機制,以避免視頻卡住的現象發生。最後再補完 simulcast 邏輯,就完成了這個硬件編解碼的支持。

以上的優化,基本上是大部分場景均可以適用的,但也有些優化要看具體場景肯定。這就比如不一樣的人口味不同,有人喜歡辣,有人喜歡原味,作不到一套方法搞定全部的食客,因而咱們作了定製化的優化來進行適應。

優化三:Audio profile

Audio 的優化作了不少,這其中挑了一個 Audio profile 的優化來說。語音場景裏,須要的編碼碼率不過高,而娛樂場景裏(好比播放伴音歌曲的),對碼率要求就高不少了,否則會丟失音質。碼率要求高了對網絡要求也會高,因此爲了應對不一樣的場景,audio 的採樣數/聲道數都是不同的。音頻硬件又是五花八門,能力不統一,若是採集上來的數據不合適,就須要作重採樣支持。同時 codec 的傾向也作了 speech 和 music 的區分,以適應不一樣的須要。WebRTC 原先的設計裏,基本只考慮了語音,跟娛樂場景相關的部分都須要優化支持。同時,爲了可以兼容更多的音頻處理/更差性能的機器,咱們在優化過程當中,將播放/採集線程進行了分離,至關於硬件要求下降了一半。

優化四:傳輸策略優化

傳輸策略要照顧實時性/清晰度/流暢度三個維度,理想中的優化固然是三個都作得更好,惋惜這三個維度是互爲掣肘的。以下圖所示:

圖6.png

這三個點裏,一個點增強了,其餘點會被影響。舉個例子:實時性要求很高,那緩存時間就得下降,這時候若是出現網絡抖動,極可能會卡頓,流暢性就受影響。因此想要同一個策略知足不一樣的需求不太現實。在項目實踐中,咱們根據不一樣的場景,設置不一樣的策略,來知足不一樣傾向的需求。

圖7.png

通訊場景通常對實時性要求高。舉個例子,你跟別人語音聊天,隔了一秒鐘才聽見對面的聲音,那麼兩我的的聊天很容易「打架」,互相搶着發言。若是是多人語音聊天,那這個現象就更加嚴重了。娛樂直播場景對清晰度要求很高,但卻能夠接受較高的延時。因此咱們在實踐過程當中給予了不一樣的策略支持,就比如作不一樣口味的飯菜來知足不一樣人的口味。

以上就是網易雲信在構建音視頻引擎過程當中的一些實踐經驗,在此分享給你們,但願能給有興趣的同窗參考。

更多內容歡迎關注 網易智企技術+ 公衆號。

相關文章
相關標籤/搜索