從入門到進階|如何基於WebRTC搭建一個視頻會議

從入門到進階|如何基於WebRTC搭建一個視頻會議

導讀:疫情期間,視頻會議等遠程辦公產品備受青睞,衆多互聯網玩家切入視頻會議市場,加重市場競爭。可是,產品雖多,可以帶來穩定可靠體驗的產品卻百裏挑一,他的難點在哪裏?視頻會議的門檻倒地有多高,又能作到怎樣的極致體驗?網易智慧企業流媒體服務器天團將會從0到1,和你們分享如何基於WebRTC來搭建一個視頻會議。

文|網易智慧企業流媒體服務器天團git

入門篇

先請出咱們今天的主角 - WebRTC,它是由谷歌推廣的實時音視頻技術棧,是音視頻領域搜索熱度最高的技術。它有多重身份,既是W3C的標準,也是一個開源項目,還有一個對應的IETF工做組(RTCWEB)。在WebRTC出現以前,音視頻通訊是遙不可及的領域,須要大量的專業積累才能入門,而如今,愈來愈多的開發者經過WebRTC來深刻了解RTC技術。github

WebRTC技術的本質是構建點對點的實時通訊,目前主流的瀏覽器,包括Chrome, Firefox, Edge等,自然就支持WebRTC協議。對入門開發者來講,選用這幾款瀏覽器,連開發客戶端的時間都省了。最簡單的Web視頻會議,只須要架設一個Web服務器,服務器兼具信令交換的能力(信令服務也能夠獨立部署),兩個瀏覽器經過Web Server交換會話信息,就能創建P2P通道來傳輸媒體流,進行1v1的視頻會議。以下圖所示:web

從入門到進階|如何基於WebRTC搭建一個視頻會議

兩個瀏覽器向Web服務器請求頁面,並進行SDP交換,而後在瀏覽器之間直接創建P2P Transport,進行媒體流傳輸。這是最簡單的WebRTC應用形式。這種簡單的媒體流直聯的方式,線上有不少教程,也能夠參考WebRTC的demo (https://webrtc.github.io/samp...,這裏不展開。算法

若是拓展到多方的視頻會議,架構是這樣的:瀏覽器

從入門到進階|如何基於WebRTC搭建一個視頻會議

能夠看到,這種」簡單」的視頻會議,有兩個風險點服務器

  1. P2P在兩個客戶端之間創建,不可避免的涉及到NAT穿透的問題,打洞的成功率直接影響P2P的可用性,在會議場景是不能接受的。
  2. 在多人場景下,本地的媒體流以拷貝的形式發送給每一個對端,對網絡帶寬是個極大的浪費,上行網絡的帶寬瓶頸決定了會議的方數上限,影響體驗,也不利於擴展。

要解決這兩個問題,就要引入媒體服務器看下面的架構圖:網絡

從入門到進階|如何基於WebRTC搭建一個視頻會議

加入媒體服務器後,每一個瀏覽器只和服務器創建媒體傳輸通道。架構

  • 媒體服務器架設在公網,P2P的可用性有保障。
  • 每一個瀏覽器只向服務器發送一路本地媒體流,由服務器負責轉發給遠端,避免了帶寬浪費。

對於視頻會議來講,這是更優的架構選擇。併發

經常使用的媒體服務器主要分爲SFU(Selected Forward Unit)和MCU(Multipoint Control Unit)SFU只負責媒體流轉發,不作太多複雜的媒體處理,併發能力會強一些。MCU除了媒體流的接收/發送,還會進行轉碼和混流,對服務器的性能要求比較高,在實時傳輸系統中,轉碼會帶來額外的延時,在選型時也必須考慮。多人視頻會議場景下的SFU/MCU架構示意如圖:框架

從入門到進階|如何基於WebRTC搭建一個視頻會議

SFU對接入的媒體流進行全網轉發,MCU對接收到的媒體流作轉碼後,只轉發一路合成後的媒體流。它們的優點和劣勢總結以下表

從入門到進階|如何基於WebRTC搭建一個視頻會議

WebRTC的生態中,有許多優秀的開源媒體服務器,下面列出部分關注度高的項目

從入門到進階|如何基於WebRTC搭建一個視頻會議

你們能夠根據本身的需求,選擇合適的項目來搭建媒體服務器。對於實時性和高併發有強要求的會議場景,筆者仍是推薦採用SFU架構,下面的進階篇中也會基於SFU展開介紹。

另外,若是不知足於瀏覽器入會,有擴展客戶端覆蓋的需求,上述的開源項目中,也有相應的native的客戶端庫,好比mediaSoup,有提供一個libmediasoupclient的C++ library,這個庫自己是基於libwebrtc的,你們能夠基於這個庫來搭建iOS/Andriod/PC的客戶端,須要必定的時間摸索編譯環境,但不會太複雜。

這還不是WebRTC生態的所有,在客戶端擴展方面,WebRTC是一直走在路上的,各類前沿的混合開發框架項目中,都能看到它的身影,好比RN/Flutter/Cordova等等,在Github上都有WebRTC開發庫,願意實踐的開發者能夠嘗試,不過,要用這些開發框架作到產品化,仍是須要必定積累的,須要踩一些坑。

到這裏,咱們完成了基礎的視頻會議搭建,或許在通話時會面對這樣那樣的質量問題,但至少實現了聽得見、看獲得,淺嘗輒止的目標已達成。下面的進階篇,就留給打算深刻學習RTC的小夥伴(須要一些音視頻基礎)。

進階篇

視頻會議的基礎是實時音視頻通訊(RTC)技術,在上一篇解決了聽得見、看獲得的問題以後,在接下來的進階篇中,咱們重點關注下如何能讓音視頻通訊穩定、流暢、可靠,也就是關乎視頻會議的質量體驗問題。

你們可能都會有這樣的體會,視頻會議老是很難保持穩定,偶爾會視頻卡住,或者聲音斷續,或是今天能夠正常完會,改天就很差。其實實時音視頻通訊的原理就是信號的採集,處理和傳輸,而其中傳輸部分是最難把控的,爲了作到實時性,咱們要摒棄長時延、可靠的TCP,選擇不可靠,但有可能作到實時的UDP。在公共互聯網上用UDP搭建傳輸網絡,它的不可靠的因子會被放大,好比時延,抖動,丟包等,都有可能影響視頻會議的體驗。

下面的章節中,咱們重點介紹實時音視頻通訊中的Quality of Service(QoS)。QoS能夠狹義地理解爲鏈路分組數據傳輸的質量指標,相對的另外一個指標是Quality of Experience(QoE),它是用戶對設備,網絡和系統整體的端到端主觀體驗。

  • QoS那些事

WebRTC中已經具有了一些保障QoS的策略,好比ARQ,FEC,Jitter Buffer,Congestion Control等,讓咱們結合前面的SFU架構來展開探討。

從入門到進階|如何基於WebRTC搭建一個視頻會議

QoS策略的主要任務是對抗影響數據傳輸的網絡變量,好比時延,抖動,丟包,帶寬等。咱們簡單介紹下QoS的常規武器

  • ARQ:自動重傳請求,是數據鏈路層的錯誤糾正協議之一,WebRTC中用到是協議中的NACK機制,即接收端監測到數據包SeqN丟失後,發送對該數據包的重傳請求,由發送端執行重傳。
  • FEC:前向糾錯,是增長數據通信可靠度的方法,利用原始數據編碼進行冗餘信息的傳輸,當傳輸中出現丟包,容許接收端根據冗餘信息重建。WebRTC利用UlpFEC進行數據保護,冗餘係數由鏈路上的丟包率決定。
  • Jitter Buffer:抖動緩衝,經過在接收端維護一個數據緩衝區,能夠對抗必定程度的網絡抖動,丟包和亂序,須要考慮的是接收延時和卡頓之間的平衡。
  • Congestion Control:擁塞控制, WebRTC利用GCC算法來控制傳輸,經過兼顧丟包和時延的算法來估計網絡可用帶寬,並以此估算值來控制源端發送碼率,避免網絡擁堵。

在典型的SFU傳輸鏈路中,媒體流(RTP數據包)由Sender發送到Receiver,媒體控制流(RTCP包)由Receiver反饋給Sender。控制流中包括了NACK, PLI, REMB, Receiver Report等反饋信息。這些反饋信息是配合QoS策略的輔助手段。

有了這些QoS策略的加持,WebRTC的視頻通話可以對抗必定程度的網絡情況,正常狀況下的通話質量能夠保障。可是,這種默認的策略也存在明顯的改進空間,好比:

  • QoS的策略是在端到端之間生效的,接收端發現丟包後,纔會向發送端發送NACK請求重傳,全鏈路的路徑(rtt)過長,影響數據重傳和恢復的效率。
  • 接收端在發現沒法恢復視頻幀後,纔會發送PLI(Picture Lost Indicator)向源端請求關鍵幀,直到下一個關鍵幀到達前,全部鏈路上的視頻幀都沒法正常解碼,影響接收端的視頻幀率,較大機率形成卡頓。
  • 針對這兩個典型的問題,咱們能夠分別嘗試改進。

從入門到進階|如何基於WebRTC搭建一個視頻會議

如上圖所示,在改進的SFU傳輸架構中,重傳請求再也不是全鏈路反饋,而是在客戶端和服務器之間進行。一方面,服務器具有了NACK請求的能力,及時發現上行鏈路的丟包,及時向發送到請求重傳。另外一方面,服務器可以及時響應接收端的NACK請求。丟包重傳的效率提高,有助於減小端到端延時,改善音視頻體驗。

對於弱網下視頻幀率較低的問題,除了優化傳輸過程當中的FEC+NACK策略以外,還能夠從源端編碼器入手調整。

常規的RTC系統中的編碼GOP是IPPP…P,每個P幀都做爲參考幀,一旦某一幀有數據包缺失,其後的全部P幀都沒法正常解碼,抗誤碼擾動的能力比較差。

一種改進的思路是,改變編碼器的參考幀選擇採用長參考幀Long-Term Reference (LTR) frames機制,好比:

從入門到進階|如何基於WebRTC搭建一個視頻會議

能夠看到,引入LTR後,P幀再也不是單一的前向參考,而是會有選擇性的參考一些固定的幀,只要這部分固定的參考幀可以完整被接收,就能確保其餘的完整幀可以正常解碼,提升接收端的視頻幀率,保障流暢。這種編碼方式是比較適合於RTC系統的,可以對抗更大的網絡抖動。

應用在視頻會議中,須要接收端實時反饋的配合。接收端藉助於RTCP,實時反饋可以正常解碼的幀信息,發送端能夠利用收集到的這些信息,選擇合適的參考幀序列(須要兼顧編碼效率),這樣端到端的配合,可以最大程度的提高實時傳輸系統的體驗。

這種反饋與編碼協同的機制,一樣適用於多人的會議場景。只不過,在多人場景中,咱們要面對更加棘手的多端擁塞控制問題。

前面介紹過WebRTC自帶的端到端擁塞控制,在會議場景下,擁塞控制須要綜合考慮各個客戶端的狀況,以下圖所示:

從入門到進階|如何基於WebRTC搭建一個視頻會議

在多人會議狀況下,各個接收端的帶寬能力是不相同的,每條鏈路的帶寬估計值都會反饋到發送端,由發送端來統一決策,控制編碼和發送碼率。這會帶來兩個潛在的問題:

  • 多條鏈路的帶寬反饋致使發送端的決策困難,編碼/發送碼率容易抖動。
  • 某一個接收端的網絡帶寬不足(如圖中的300k下行),發送端就會下降碼率以適配當前帶寬,致使每一個接收端的體驗都會降低,這顯然是不合理的。

解決這些問題,咱們就要來改進擁塞控制模型。大體的思路是,在SFU上實現帶寬估計反饋,以及下行的擁塞控制。將端到端的擁塞策略,演進爲分段的擁塞控制策略。

理想狀況下,發送端會根據上行的帶寬估計值控制源端編碼和發送碼率,SFU則會利用下行的帶寬估計值,來控制下發給各接收端的最高碼率。

然而,現實問題是,當SFU只有一路視頻能夠轉發時,如何根據各鏈路的帶寬狀況進行下發控制,有點巧婦難爲無米之炊的感受。

這裏要藉助於兩種源端編碼策略 - Simulcast和SVC。

Simulcast:同步廣播,指的是同時編碼/發送多路視頻流,好比常規發送一路720p,外加一路180p的流,這樣在SFU下發給接收端的時候,能夠根據下行帶寬的限制,選擇下發不一樣分辨率的流,照顧到每一個端的體驗。應用Simulcast的系統示意:

從入門到進階|如何基於WebRTC搭建一個視頻會議

SVC:可伸縮編碼,使用基於層次的方法,提供時間或空間可伸縮編碼組合。在RTC的應用中,一般會選用時域SVC,經過改變幀率來實現伸縮性。SFU能夠根據下行的實際帶寬,從同一路SVC視頻流中解析出不一樣的時域分層,分別傳輸給各個接收端,一樣能夠實現差別化的視頻流轉發。

從入門到進階|如何基於WebRTC搭建一個視頻會議

Simulcast和SVC在實際應用中各有優劣,Simulcast多路流的分辨率跨度大,主觀體驗不佳;SVC的時域分層會影響幀率,容易出現卡頓。

從入門到進階|如何基於WebRTC搭建一個視頻會議

  • 實時傳輸網絡

前一節重點介紹了WebRTC QoS的基本配置,以及進階的實踐方向。有了這些武器,能夠在上下行網絡質量有波動時,還能保障較好的音視頻體驗。

在視頻會議的搭建過程當中,QoS策略的保障是一方面,傳輸鏈路的選擇也一樣重要。

到目前爲止,咱們介紹的視頻會議架構仍是中心服務器轉發,擺在咱們面前有幾個顯而易見的問題:

  • 用戶遠距離接入,尤爲是跨國、跨地區時,傳輸鏈路質量沒有保障。
  • 國內的跨運營商之間接入,網絡抖動大,影響會議質量。
  • 單點服務器的容量和負載受限制。

若是但願咱們的視頻會議是穩定、可靠的,解決上面的全部問題,必須構建一個具有智能調度的實時傳輸網絡。

從入門到進階|如何基於WebRTC搭建一個視頻會議

總體網絡傳輸的調度見上圖,幾點簡要的說明:

  • 分區域/分運營商部署SFU服務器,用戶經過接入服務實現就近接入,保障了最後一千米的質量。
  • 靈活/按需部署路由節點,經過路由分配服務,可以根據實時網絡質量選擇最優的傳輸路徑。
  • 分佈式的SFU更有利於會議方數的擴展和服務擴容
  • 須要保障傳輸s網絡內部的數據傳輸質量,能夠嘗試QUIC。

結合上述兩點,有了可靠的傳輸網絡,加上QoS保障的上下行質量,才能實現讓人放心的視頻會議體驗。

  • 其 他

除了網絡傳輸和QoS以外,視頻會議的質量體驗也和客戶端的表現相關,一些端側的疑難雜症,好比設備可用性,回聲消除,雙講抑制等等,必定程度上決定了會議產品的成敗。這一部分的技術細節,將會在從此的公號文章中分享。

To Be Continued

自建一個視頻會議產品絕非一朝一夕之事。視頻會議系統龐大,文中介紹的也只是一小部分。將來咱們會針對技術細節,結合網易實踐,進行持續的分享,甚至推出免費的系列課程。

另外,若是你對本篇文章有任何疑問,或想針對某一細節繼續探討,歡迎你們關注公衆號,留下你的問題,對話網易智慧企業流媒體服務器天團。咱們也會按期彙總你們的問題,整理成專題文章發佈,但願給你們帶來更多收穫。

相關文章
相關標籤/搜索