从入门到进阶|如何基于WebRTC搭建一个视频会议
文|網(wǎng)易智慧企業(yè)流媒體服務(wù)器天團(tuán)
?
導(dǎo)讀:疫情期間,視頻會(huì)議等遠(yuǎn)程辦公產(chǎn)品備受青睞,眾多互聯(lián)網(wǎng)玩家切入視頻會(huì)議市場(chǎng),加劇市場(chǎng)競(jìng)爭(zhēng)。但是,產(chǎn)品雖多,能夠帶來穩(wěn)定可靠體驗(yàn)的產(chǎn)品卻鳳毛麟角,它的難點(diǎn)在哪里?視頻會(huì)議的門檻到底有多高,又能夠做到怎樣的極致體驗(yàn)?網(wǎng)易智慧企業(yè)流媒體服務(wù)器天團(tuán)將會(huì)從0到1,和大家分享如何基于WebRTC來搭建一個(gè)視頻會(huì)議。
?
入門篇
先請(qǐng)出我們今天的主角 - WebRTC,它是由谷歌推廣的實(shí)時(shí)音視頻技術(shù)棧,是音視頻領(lǐng)域搜索熱度最高的技術(shù)。它有多重身份,既是W3C的標(biāo)準(zhǔn),也是一個(gè)開源項(xiàng)目,還有一個(gè)對(duì)應(yīng)的IETF工作組(RTCWEB)。在WebRTC出現(xiàn)之前,音視頻通信是高不可攀的領(lǐng)域,需要大量的專業(yè)積累才能入門,而現(xiàn)在,越來越多的開發(fā)者通過WebRTC來深入了解RTC技術(shù)。
WebRTC技術(shù)的本質(zhì)是構(gòu)建點(diǎn)對(duì)點(diǎn)的實(shí)時(shí)通信,目前主流的瀏覽器,包括Chrome, Firefox, Edge等,天然就支持WebRTC協(xié)議。對(duì)入門開發(fā)者來說,選用這幾款瀏覽器,連開發(fā)客戶端的時(shí)間都省了。最簡(jiǎn)單的Web視頻會(huì)議,只需要架設(shè)一個(gè)Web服務(wù)器,服務(wù)器兼具信令交換的能力(信令服務(wù)也可以獨(dú)立部署),兩個(gè)瀏覽器通過Web Server交換會(huì)話信息,就能建立P2P通道來傳輸媒體流,進(jìn)行1v1的視頻會(huì)議。如下圖所示。
?
兩個(gè)瀏覽器向Web服務(wù)器請(qǐng)求頁(yè)面,并進(jìn)行SDP交換,然后在瀏覽器之間直接建立P2P Transport,進(jìn)行媒體流傳輸。這是最簡(jiǎn)單的WebRTC應(yīng)用形式。
這種簡(jiǎn)單的媒體流直聯(lián)的方式,線上有很多教程,也可以參考WebRTC的demo (https://webrtc.github.io/samples/),這里不展開。
如果拓展到多方的視頻會(huì)議,架構(gòu)是這樣的:
?
可以看到,這種”簡(jiǎn)單”的視頻會(huì)議,有兩個(gè)風(fēng)險(xiǎn)點(diǎn):
要解決這兩個(gè)問題,就要引入媒體服務(wù)器。看下面的架構(gòu)圖:
?
加入媒體服務(wù)器后,每個(gè)瀏覽器只和服務(wù)器建立媒體傳輸通道。
- 媒體服務(wù)器架設(shè)在公網(wǎng),P2P的可用性有保障。
- 每個(gè)瀏覽器只向服務(wù)器發(fā)送一路本地媒體流,由服務(wù)器負(fù)責(zé)轉(zhuǎn)發(fā)給遠(yuǎn)端,避免了帶寬浪費(fèi)。
對(duì)于視頻會(huì)議來說,這是更優(yōu)的架構(gòu)選擇。
常用的媒體服務(wù)器主要分為SFU(Selected Forward Unit)和MCU(Multipoint Control Unit),SFU只負(fù)責(zé)媒體流轉(zhuǎn)發(fā),不做太多復(fù)雜的媒體處理,并發(fā)能力會(huì)強(qiáng)一些。MCU除了媒體流的接收/發(fā)送,還會(huì)進(jìn)行轉(zhuǎn)碼和混流,對(duì)服務(wù)器的性能要求比較高,在實(shí)時(shí)傳輸系統(tǒng)中,轉(zhuǎn)碼會(huì)帶來額外的延時(shí),在選型時(shí)也必須考慮。多人視頻會(huì)議場(chǎng)景下的SFU/MCU架構(gòu)示意如圖:
SFU對(duì)接入的媒體流進(jìn)行全網(wǎng)轉(zhuǎn)發(fā),MCU對(duì)接收到的媒體流做轉(zhuǎn)碼后,只轉(zhuǎn)發(fā)一路合成后的媒體流。它們的優(yōu)勢(shì)和劣勢(shì)總結(jié)如下表:
WebRTC的生態(tài)中,有許多優(yōu)秀的開源媒體服務(wù)器,下面列出部分關(guān)注度高的項(xiàng)目。
?
| Project | SFU | MCU | LIcense |
| Janus | ?? | ?? | GPL v3 |
| Licode | ?? | ?? | MIT |
| MediaSoup | ?? | ?? | ISC |
| Kurento | ?? | ?? | Apache2 |
| Jitsi | ?? | ?? | Apache2 |
?
| ? | 優(yōu)勢(shì) | 劣勢(shì) |
| SFU | 靈活分發(fā),并發(fā)高 | 下行轉(zhuǎn)發(fā)路數(shù)多,帶寬占用高,多方通話影響體驗(yàn) |
| MCU | 轉(zhuǎn)發(fā)流數(shù)少,下行帶寬占用少 | 服務(wù)器性能要求高,部署成本高,實(shí)時(shí)性稍差 |
大家可以根據(jù)自己的需求,選擇合適的項(xiàng)目來搭建媒體服務(wù)器。對(duì)于實(shí)時(shí)性和高并發(fā)有強(qiáng)要求的會(huì)議場(chǎng)景,筆者還是推薦采用SFU架構(gòu),下面的進(jìn)階篇中也會(huì)基于SFU展開介紹。
另外,如果不滿足于瀏覽器入會(huì),有擴(kuò)展客戶端覆蓋的需求,上述的開源項(xiàng)目中,也有相應(yīng)的native的客戶端庫(kù),比如mediaSoup,有提供一個(gè)libmediasoupclient的C++ library,這個(gè)庫(kù)本身是基于libwebrtc的,大家可以基于這個(gè)庫(kù)來搭建iOS/Andriod/PC的客戶端,需要一定的時(shí)間摸索編譯環(huán)境,但不會(huì)太復(fù)雜。
這還不是WebRTC生態(tài)的全部,在客戶端擴(kuò)展方面,WebRTC是一直走在路上的,各種前沿的混合開發(fā)框架項(xiàng)目中,都能看到它的身影,比如RN/Flutter/Cordova等等,在Github上都有WebRTC開發(fā)庫(kù),愿意實(shí)踐的開發(fā)者可以嘗試,不過,要用這些開發(fā)框架做到產(chǎn)品化,還是需要一定積累的,需要踩一些坑。
到這里,我們完成了基礎(chǔ)的視頻會(huì)議搭建,或許在通話時(shí)會(huì)面對(duì)這樣那樣的質(zhì)量問題,但至少實(shí)現(xiàn)了聽得見、看得到,淺嘗則止的目標(biāo)已達(dá)成。下面的進(jìn)階篇,就留給打算深入學(xué)習(xí)RTC的小伙伴(需要一些音視頻基礎(chǔ))。
?
進(jìn)階篇
視頻會(huì)議的基礎(chǔ)是實(shí)時(shí)音視頻通信(RTC)技術(shù),在上一篇解決了聽得見、看得到的問題之后,在接下來的進(jìn)階篇中,我們重點(diǎn)關(guān)注下如何能讓音視頻通信穩(wěn)定、流暢、可靠,也就是關(guān)乎視頻會(huì)議的質(zhì)量體驗(yàn)問題。
大家可能都會(huì)有這樣的體會(huì),視頻會(huì)議總是很難保持穩(wěn)定,偶爾會(huì)視頻卡住,或者聲音斷續(xù),或是今天可以正常完會(huì),改天就不好。其實(shí)實(shí)時(shí)音視頻通信的原理就是信號(hào)的采集,處理和傳輸,而其中傳輸部分是最難把控的,為了做到實(shí)時(shí)性,我們要摒棄長(zhǎng)時(shí)延、可靠的TCP,選擇不可靠,但有可能做到實(shí)時(shí)的UDP。在公共互聯(lián)網(wǎng)上用UDP搭建傳輸網(wǎng)絡(luò),它的不可靠的因子會(huì)被放大,比如時(shí)延,抖動(dòng),丟包等,都有可能影響視頻會(huì)議的體驗(yàn)。
下面的章節(jié)中,我們重點(diǎn)介紹實(shí)時(shí)音視頻通信中的Quality of Service(QoS)。QoS可以狹義地理解為鏈路分組數(shù)據(jù)傳輸?shù)馁|(zhì)量指標(biāo),相對(duì)的另一個(gè)指標(biāo)是Quality of Experience(QoE),它是用戶對(duì)設(shè)備,網(wǎng)絡(luò)和系統(tǒng)總體的端到端主觀體驗(yàn)。
?
QoS那些事
WebRTC中已經(jīng)具備了一些保障QoS的策略,比如ARQ,FEC,Jitter Buffer,Congestion Control等,讓我們結(jié)合前面的SFU架構(gòu)來展開探討。
QoS策略的主要任務(wù)是對(duì)抗影響數(shù)據(jù)傳輸?shù)木W(wǎng)絡(luò)變量,比如時(shí)延,抖動(dòng),丟包,帶寬等。我們簡(jiǎn)單介紹下QoS的常規(guī)武器。
在典型的SFU傳輸鏈路中,媒體流(RTP數(shù)據(jù)包)由Sender發(fā)送到Receiver,媒體控制流(RTCP包)由Receiver反饋給Sender。控制流中包括了NACK, PLI, REMB, Receiver Report等反饋信息。這些反饋信息是配合QoS策略的輔助手段。
有了這些QoS策略的加持,WebRTC的視頻通話能夠?qū)挂欢ǔ潭鹊木W(wǎng)絡(luò)狀況,正常情況下的通話質(zhì)量可以保障。但是,這種默認(rèn)的策略也存在明顯的改進(jìn)空間,比如:
針對(duì)這兩個(gè)典型的問題,我們可以分別嘗試改進(jìn)。
如上圖所示,在改進(jìn)的SFU傳輸架構(gòu)中,重傳請(qǐng)求不再是全鏈路反饋,而是在客戶端和服務(wù)器之間進(jìn)行。一方面,服務(wù)器具備了NACK請(qǐng)求的能力,及時(shí)發(fā)現(xiàn)上行鏈路的丟包,及時(shí)向發(fā)送到請(qǐng)求重傳。另一方面,服務(wù)器能夠及時(shí)響應(yīng)接收端的NACK請(qǐng)求。丟包重傳的效率提升,有助于減少端到端延時(shí),改善音視頻體驗(yàn)。
對(duì)于弱網(wǎng)下視頻幀率較低的問題,除了優(yōu)化傳輸過程中的FEC+NACK策略之外,還可以從源端編碼器入手調(diào)整。
常規(guī)的RTC系統(tǒng)中的編碼GOP是IPPP…P,每一個(gè)P幀都作為參考幀,一旦某一幀有數(shù)據(jù)包缺失,其后的所有P幀都無法正常解碼,抗誤碼擾動(dòng)的能力比較差。
一種改進(jìn)的思路是,改變編碼器的參考幀選擇,采用長(zhǎng)參考幀Long-Term Reference (LTR) frames機(jī)制,比如:
?
可以看到,引入LTR后,P幀不再是單一的前向參考,而是會(huì)有選擇性的參考一些固定的幀,只要這部分固定的參考幀能夠完整被接收,就能確保其他的完整幀能夠正常解碼,提高接收端的視頻幀率,保障流暢。這種編碼方式是比較適合于RTC系統(tǒng)的,能夠?qū)垢蟮木W(wǎng)絡(luò)抖動(dòng)。
應(yīng)用在視頻會(huì)議中,需要接收端實(shí)時(shí)反饋的配合。接收端借助于RTCP,實(shí)時(shí)反饋能夠正常解碼的幀信息,發(fā)送端可以利用收集到的這些信息,選擇合適的參考幀序列(需要兼顧編碼效率),這樣端到端的配合,能夠最大程度的提升實(shí)時(shí)傳輸系統(tǒng)的體驗(yàn)。
這種反饋與編碼協(xié)同的機(jī)制,同樣適用于多人的會(huì)議場(chǎng)景。只不過,在多人場(chǎng)景中,我們要面對(duì)更加棘手的多端擁塞控制問題。
前面介紹過WebRTC自帶的端到端擁塞控制,在會(huì)議場(chǎng)景下,擁塞控制需要綜合考慮各個(gè)客戶端的情況,如下圖所示:
在多人會(huì)議情況下,各個(gè)接收端的帶寬能力是不相同的,每條鏈路的帶寬估計(jì)值都會(huì)反饋到發(fā)送端,由發(fā)送端來統(tǒng)一決策,控制編碼和發(fā)送碼率。這會(huì)帶來兩個(gè)潛在的問題:
?
解決這些問題,我們就要來改進(jìn)擁塞控制模型。大致的思路是,在SFU上實(shí)現(xiàn)帶寬估計(jì)反饋,以及下行的擁塞控制。將端到端的擁塞策略,演進(jìn)為分段的擁塞控制策略。
理想情況下,發(fā)送端會(huì)根據(jù)上行的帶寬估計(jì)值控制源端編碼和發(fā)送碼率,SFU則會(huì)利用下行的帶寬估計(jì)值,來控制下發(fā)給各接收端的最高碼率。
然而,現(xiàn)實(shí)問題是,當(dāng)SFU只有一路視頻可以轉(zhuǎn)發(fā)時(shí),如何根據(jù)各鏈路的帶寬情況進(jìn)行下發(fā)控制,有點(diǎn)巧婦難為無米之炊的感覺。
這里要借助于兩種源端編碼策略 - Simulcast和SVC。
Simulcast:同步廣播,指的是同時(shí)編碼/發(fā)送多路視頻流,比如常規(guī)發(fā)送一路720p,外加一路180p的流,這樣在SFU下發(fā)給接收端的時(shí)候,可以根據(jù)下行帶寬的限制,選擇下發(fā)不同分辨率的流,照顧到每個(gè)端的體驗(yàn)。
應(yīng)用Simulcast的系統(tǒng)示意:
SVC:可伸縮編碼,使用基于層次的方法,提供時(shí)間或空間可伸縮編碼組合。在RTC的應(yīng)用中,通常會(huì)選用時(shí)域SVC,通過改變幀率來實(shí)現(xiàn)伸縮性。SFU可以根據(jù)下行的實(shí)際帶寬,從同一路SVC視頻流中解析出不同的時(shí)域分層,分別傳輸給各個(gè)接收端,同樣可以實(shí)現(xiàn)差異化的視頻流轉(zhuǎn)發(fā)。
?
| ? | 優(yōu)勢(shì) | 劣勢(shì) |
| Simulcast | 每路流都能保障幀率 | 上行帶寬占用高;分辨率跨度大 |
| SVC | 同一路視頻流,上行帶寬合理 | 時(shí)域分層影響接收幀率 |
?
Simulcast和SVC在實(shí)際應(yīng)用中各有優(yōu)劣,Simulcast多路流的分辨率跨度大,主觀體驗(yàn)不佳;SVC的時(shí)域分層會(huì)影響幀率,容易出現(xiàn)卡頓。
?
實(shí)時(shí)傳輸網(wǎng)絡(luò)
前一節(jié)重點(diǎn)介紹了WebRTC QoS的基本配置,以及進(jìn)階的實(shí)踐方向。有了這些武器,可以在上下行網(wǎng)絡(luò)質(zhì)量有波動(dòng)時(shí),還能保障較好的音視頻體驗(yàn)。
在視頻會(huì)議的搭建過程中,QoS策略的保障是一方面,傳輸鏈路的選擇也同樣重要。
到目前為止,我們介紹的視頻會(huì)議架構(gòu)還是中心服務(wù)器轉(zhuǎn)發(fā),擺在我們面前有幾個(gè)顯而易見的問題:
單點(diǎn)服務(wù)器的容量和負(fù)載受限制。
如果希望我們的視頻會(huì)議是穩(wěn)定、可靠的,解決上面的所有問題,必須構(gòu)建一個(gè)具備智能調(diào)度的實(shí)時(shí)傳輸網(wǎng)絡(luò)。
整體網(wǎng)絡(luò)傳輸?shù)恼{(diào)度見上圖,幾點(diǎn)簡(jiǎn)要的說明:
結(jié)合上述兩點(diǎn),有了可靠的傳輸網(wǎng)絡(luò),加上QoS保障的上下行質(zhì)量,才能實(shí)現(xiàn)讓人放心的視頻會(huì)議體驗(yàn)。
?
其他
除了網(wǎng)絡(luò)傳輸和QoS之外,視頻會(huì)議的質(zhì)量體驗(yàn)也和客戶端的表現(xiàn)相關(guān),一些端側(cè)的疑難雜癥,比如設(shè)備可用性,回聲消除,雙講抑制等等,一定程度上決定了會(huì)議產(chǎn)品的成敗。這一部分的技術(shù)細(xì)節(jié),將會(huì)在今后的公號(hào)文章中分享。
?
?
To Be Continued
?
自建一個(gè)視頻會(huì)議產(chǎn)品絕非一朝一夕之事。視頻會(huì)議系統(tǒng)龐大,文中介紹的也只是一小部分。未來我們會(huì)針對(duì)技術(shù)細(xì)節(jié),結(jié)合網(wǎng)易實(shí)踐,進(jìn)行持續(xù)的分享,甚至推出免費(fèi)的系列課程。
?
另外,如果你對(duì)本篇文章有任何疑問,或想針對(duì)某一細(xì)節(jié)繼續(xù)探討,歡迎大家關(guān)注“網(wǎng)易智慧企業(yè)技術(shù)+”公眾號(hào),留下你的問題,對(duì)話網(wǎng)易智慧企業(yè)流媒體服務(wù)器天團(tuán)。我們也會(huì)定期匯總大家的問題,整理成專題文章發(fā)布,希望給大家?guī)砀嗍斋@。
?
?
福利時(shí)間
初次見面,
“網(wǎng)易智慧企業(yè)技術(shù)+”為各位朋友準(zhǔn)備了一些禮物:
網(wǎng)易云音樂黑膠VIP年卡? ?3張?
網(wǎng)易嚴(yán)選旅行頸枕眼罩套裝? ?10份
?
玩法如下:
Step1:關(guān)注“網(wǎng)易智慧企業(yè)技術(shù)+”公眾號(hào)
Step2:轉(zhuǎn)發(fā)本篇文章至朋友圈并截圖
Step3:將截圖上傳至抽獎(jiǎng)表單
(若無自動(dòng)回復(fù),可回復(fù)關(guān)鍵詞“抽獎(jiǎng)”獲取鏈接)
?
4月15日晚上9:30統(tǒng)一開獎(jiǎng)
?
總結(jié)
以上是生活随笔為你收集整理的从入门到进阶|如何基于WebRTC搭建一个视频会议的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何用杠铃策略,构建你的“反脆弱性”
- 下一篇: 开源|如何开发一个高性能的redis c