聲網(wǎng)Agora 開(kāi)發(fā)者社區(qū)聯(lián)合 InfoQ 共同策劃,邀請(qǐng)了聲網(wǎng)Agora 開(kāi)發(fā)者社區(qū)中的多位技術(shù)專(zhuān)家,從視頻傳輸、計(jì)算機(jī)視覺(jué)、編解碼標(biāo)準(zhǔn)發(fā)展、WebRTC、機(jī)器學(xué)習(xí)、音頻技術(shù)等角度,共同撰寫(xiě)「2021 實(shí)時(shí)互動(dòng)技術(shù)展望系列」,一窺技術(shù)新趨勢(shì)。本系列內(nèi)容由聲網(wǎng) Agora 開(kāi)發(fā)者社區(qū) 與 InfoQ 聯(lián)合策劃,并由 InfoQ 審校,首發(fā)于 InfoQ。
2020 年,WebRTC 發(fā)生了很多變化。WebRTC 其實(shí)就是一個(gè)客戶(hù)端庫(kù)。大家都知道它是開(kāi)源的。盡管 Google 大力地在支持 WebRTC,但社區(qū)的力量同樣功不可沒(méi)。
WebRTC 對(duì)于桌面平臺(tái)、瀏覽器端實(shí)現(xiàn)音視頻交互來(lái)講十分重要。因?yàn)樵谀憧梢栽贋g覽器上運(yùn)行任何一種服務(wù),并進(jìn)行安全檢查,無(wú)需安裝任何應(yīng)用。這是此前開(kāi)發(fā)者使用該開(kāi)源庫(kù)的主要方式。
但 2020 年,瀏覽器的發(fā)展方向變了。首先講講 Microsoft,它將自研的瀏覽器引擎替換為基于 Chromium 的引擎,同時(shí)它們也成為了 WebRTC 的積極貢獻(xiàn)者。Microsoft 貢獻(xiàn)之一是 perfect negotiation,它使得兩端以更穩(wěn)妥的形式協(xié)商。而且,它們還改良了屏幕捕獲,使其效率更高。
另一方面,還有 Safari。蘋(píng)果的 Safari 還在繼續(xù)改進(jìn)他們 WebRTC API。激動(dòng)人心的是,最新一版的 Safari Tech Preview 中已支持了 VP9,而且還支持硬件加速,大家可以在 Safari 的“開(kāi)發(fā)者設(shè)置”中啟用它。
火狐瀏覽器增加了重傳以及 transport-cc,這有助于更好地估計(jì)可用帶寬,從而改善媒體質(zhì)量。
另一方面,Project Zero——Google 負(fù)責(zé)產(chǎn)品安全性的團(tuán)隊(duì),通過(guò)尋找漏洞,幫助提高 WebRTC 的安全性。這意味著如果你的庫(kù)不基于瀏覽器,及時(shí)更新 WebRTC 庫(kù)、遵守說(shuō)明就更加重要了。
另一件激動(dòng)人心的事情就是,2020 年,云游戲已經(jīng)上線了。它的實(shí)現(xiàn)有賴(lài)于 WebRTC。Stadia(Google 的云游戲平臺(tái))已于 2019 年底推出,但 2020 年初才正式在瀏覽器得以支持。其云游戲搭載 VP9,提供 4k、HDR 圖像和環(huán)繞聲體驗(yàn)。這些都會(huì)通過(guò) WebRTC 進(jìn)行傳輸。
數(shù)月前,NVIDIA 也發(fā)布了適用于 Chromebook 的 GeForce Now,同樣使用了 WebRTC。最近,Microsoft 和亞馬遜也宣布支持基于瀏覽器的云游戲開(kāi)發(fā)。這確實(shí)促使 WebRTC 從數(shù)百毫秒延遲降低到了數(shù)十毫秒延遲,同時(shí)開(kāi)啟了全新的應(yīng)用場(chǎng)景。但最重要的是, 2020 年,實(shí)時(shí)通訊(RTC)對(duì)于每個(gè)人來(lái)說(shuō)都是必不可少的一部分。因此,許多網(wǎng)絡(luò)服務(wù)的使用率暴漲,漲幅從十倍到幾百倍不等。大家打語(yǔ)音電話(huà)的次數(shù)更多了,時(shí)間更久了,群組數(shù)量和成員人數(shù)也增加了, 線上交流越來(lái)越多。所以我們需要更豐富的互動(dòng)方式。
從 Google 的角度來(lái)看, 在疫情爆發(fā)的頭 2、3 個(gè)月內(nèi),我們的最大需求容量增長(zhǎng)了 30 倍。所以即使是 Google,要確保后端和所有系統(tǒng)功能都可以應(yīng)對(duì)這么大的增長(zhǎng),我們也付出了很多努力。
在變化面前, WebRTC 和實(shí)時(shí)通信使用量激增。大眾的日常習(xí)慣也在變化,F(xiàn)在不只在公司能工作, 自己的臥室、廚房里都是工作場(chǎng)所了。由于“社交距離”,面對(duì)面交流變得不再現(xiàn)實(shí),我們需要其它與他人社交的方法。我們只能通過(guò)視頻,依據(jù)別人的表情猜測(cè)他的意圖,此時(shí)高清的視頻質(zhì)量就顯得更加重要了。
每個(gè)人協(xié)作的方式不同,可能是因?yàn)槲覀冇玫脑O(shè)備不一樣。如果你在公司, 你用的可能是臺(tái)式機(jī),那你可能會(huì)用它在會(huì)議室里開(kāi)會(huì)。而下班之后,你可能會(huì)帶你的筆記本電腦回家。但現(xiàn)在人們都在用筆記本處理各種事宜,比如同時(shí)運(yùn)行應(yīng)用、視頻會(huì)議和文字聊天。這種場(chǎng)景下,電腦的使用率非常高。我們看到學(xué)校里的孩子們也在用筆記本電腦,比如 Chromebook, 但他們電腦的性能相對(duì)差一點(diǎn)。社交、學(xué)習(xí)線上化之后,電腦的任務(wù)處理量突然增大, 所以開(kāi)展該 WebRTC 項(xiàng)目的意義在于我們需要幫助擴(kuò)展 WebRTC,確保其運(yùn)行良好。
其次,我們需要為 Web 開(kāi)發(fā)者和實(shí)時(shí)通訊開(kāi)發(fā)者提供更大的靈活度,讓他們可以在當(dāng)下開(kāi)發(fā)出新的互動(dòng)體驗(yàn)。當(dāng)疫情爆發(fā)時(shí),它阻礙我們了在 Chrome 中開(kāi)展的所有實(shí)驗(yàn),于是我們所做的一件事情就是專(zhuān)注于服務(wù)的擴(kuò)展、維護(hù)。但這遠(yuǎn)遠(yuǎn)不夠,特別是在提高性能方面,我們需要做得更好。
大家可以猜一猜,如果你要在任何使用 WebRTC 的瀏覽器中開(kāi)展實(shí)時(shí)服務(wù), 最耗性能的部分會(huì)是什么呢?是視頻編碼?音頻編碼?網(wǎng)絡(luò)適配?(因?yàn)槟銜?huì)考慮到可能會(huì)有丟包和網(wǎng)絡(luò)變化)又或者是渲染?
當(dāng)你想在屏幕顯示攝像頭采集的畫(huà)面時(shí),我們可以來(lái)看看瀏覽器中發(fā)生了什么。我們假設(shè)你有一個(gè)通過(guò) USB 驅(qū)動(dòng)程序輸入的攝像頭, 驅(qū)動(dòng)運(yùn)行,開(kāi)始處理,攝像頭可能還會(huì)進(jìn)行人臉檢測(cè)、亮度調(diào)整等操作。這要經(jīng)過(guò)瀏覽器內(nèi)的系統(tǒng),Chrome 和其它瀏覽器都是多進(jìn)程的。多進(jìn)程有助于瀏覽器的穩(wěn)定性和安全性,比如一個(gè)組件或一個(gè)頁(yè)面崩潰,或存在安全漏洞,那么它就會(huì)與其他沙盒中的組件隔離。但這也意味著進(jìn)程間有大量的通信。所以如果你有一幀視頻數(shù)據(jù)從攝像頭被采集,它可能是 MJPEG 格式。當(dāng)它開(kāi)始渲染你定義媒體流的頁(yè)面時(shí), 格式可能為 I420。當(dāng)從渲染進(jìn)程轉(zhuǎn)到 GPU 進(jìn)程(需要實(shí)際在屏幕上繪制)時(shí),需要提供最高質(zhì)量的數(shù)據(jù),此時(shí)數(shù)據(jù)可能是 RGB 格式。當(dāng)它再次進(jìn)入操作系統(tǒng),在屏幕上進(jìn)行合成時(shí), 可能需要一個(gè) alpha 層, 格式又要變。這中間涉及到大量轉(zhuǎn)換和復(fù)制步驟。由此可見(jiàn), 無(wú)論內(nèi)容來(lái)自攝像頭還是某一終端,僅僅把它放到屏幕上的視頻幀中就要花費(fèi)大量的處理時(shí)間。所以這就是 WebRTC 服務(wù)中最復(fù)雜的部分——渲染。

這也是我們做了很多優(yōu)化的地方。渲染變得更加高效了,可以確保我們不會(huì)在每次更新視頻幀時(shí)都重新繪制。如果同時(shí)有多個(gè)視頻,我們會(huì)把他們同步,再做其他操作。Chrome 團(tuán)隊(duì)優(yōu)化了內(nèi)存分配,確保每個(gè)視頻幀都以最有效的方式得到分配。我們還改進(jìn)了 Chrome OS 上的操作系統(tǒng)調(diào)度,以確保視頻服務(wù)即使負(fù)載過(guò)重也能保證交互和響應(yīng)。接下來(lái)的幾個(gè)月里,我們將致力于從攝像頭采集到視頻幀渲染到屏幕這個(gè)過(guò)程的“零拷貝”。我們希望不會(huì)出現(xiàn)一次拷貝或轉(zhuǎn)換,但所有信息都會(huì)以最高效的方式保存在圖片內(nèi)存里的。
同時(shí),我們也致力于使刷新率適應(yīng)視頻幀率。所以在沒(méi)有任何變化的情況下,我們不需要 60Hz 的屏幕刷新率,但要適應(yīng)視頻的幀速率,例如 25 秒一次。以下是我們覺(jué)得有用的建議:
1、避免耗時(shí)耗力的擴(kuò)展操作,在 incongnito 模式下進(jìn)行測(cè)試。
避免耗時(shí)耗力的擴(kuò)展操作很難,它可以干擾你的服務(wù)進(jìn)程,減緩你的服務(wù)速度。
2、避免安全程序干擾瀏覽器運(yùn)行
殺毒軟件若要做深度數(shù)據(jù)包檢查或阻止數(shù)據(jù)包,會(huì)占用大量 CPU。
3、通過(guò) Intel Power Gadgets 來(lái)測(cè)試
我們建議你用 Intel Power Gadgets 看看你的服務(wù)用了多少能耗。它會(huì)比只看 CPU 百分比直觀的多。
4、花哨的視頻效果會(huì)占用更多性能
如果你用一些花哨的動(dòng)畫(huà), 比如會(huì)動(dòng)的圓點(diǎn)來(lái)裝飾你的視頻幀,就會(huì)占用更多性能。盡管看起來(lái)不錯(cuò),但它可能會(huì)導(dǎo)致視頻幀卡頓一番才能渲染在屏幕上。
5、攝像頭分辨率設(shè)置與傳輸分辨率一致
如果你使用攝像頭采集,請(qǐng)確保打開(kāi)攝像頭時(shí)將其分辨率的設(shè)置,與你調(diào)用 getUserMedia 時(shí)的設(shè)置保持一致。如果你打開(kāi)攝像頭,設(shè)置了高清畫(huà)質(zhì),格式為 VGA,那么勢(shì)必需要轉(zhuǎn)換很多字節(jié)的信息都會(huì)被扔掉。
6、要留意 WebAudio 的使用
WebAudio 可能比預(yù)期需要更多 CPU 來(lái)處理。
關(guān)于視頻編解碼
視頻編解碼器可用于構(gòu)建更高性能服務(wù)器。因?yàn)椴粌H CPU 資源很重要, 若你構(gòu)建網(wǎng)絡(luò)相關(guān)的服務(wù),視頻編解碼器就顯得重要起來(lái)了。如果你要把業(yè)務(wù)拓展一百倍, Google 提供一款免費(fèi)的編解碼器,VP8、VP9、AV1,并且他在所有瀏覽器中都可用。

VP8 是目前為止瀏覽器內(nèi)部使用最多的版本,所有瀏覽器都支持它。VP9 同樣在市場(chǎng)中流通很多年了,也一直在改進(jìn)。它具備 30%-50% 的節(jié)約率,以及如支持 HDR 和 4K 的高質(zhì)量功能。同時(shí),它廣泛應(yīng)用于谷歌內(nèi)部,支持 Stadia 及其他內(nèi)部服務(wù)。因?yàn)樗?VP8 中沒(méi)有的功能,即能幫助你更好地適應(yīng)高低帶寬連接的轉(zhuǎn)換。然后是 AV1。AV1 也即將在 WebRTC、一些開(kāi)源實(shí)現(xiàn)和瀏覽器中使用。大多數(shù)瀏覽器已經(jīng)可以使用它進(jìn)行流式傳輸。希望明年能正式啟用它。實(shí)際上,微軟剛剛宣布他們的操作系統(tǒng)將支持硬件加速 AV1。性能的提升給予了開(kāi)發(fā)者更大空間。
WebRTC NV(Next Version)
發(fā)布 WebRTC 1.0 之后,我們就和社區(qū)一起研發(fā)下一個(gè)版本, 該版本叫“NV”。該版本意在支持當(dāng)前 WebRTC API 不可能或很難實(shí)現(xiàn)的新用例,比如虛擬現(xiàn)實(shí)。對(duì)于虛擬現(xiàn)實(shí)特效,就像前面提到過(guò)的筆記本電腦和機(jī)器學(xué)習(xí)的例子一樣, 為了能夠使用 WebRTC API 運(yùn)行,我們需要更好地掌握媒體處理的技能, 比如更好控制傳輸和擁塞,使用編解碼器進(jìn)行更多自定義操作等等。
在以上這些目標(biāo)上,WebRTC NV 的思路是不定義全新 API。目前已經(jīng)有兩個(gè) API 和 WebRTC,PeerConnetion 和 getUserMedia 了。我們不會(huì)重新定義它們,從頭開(kāi)始研發(fā)。相反,我們正在做的是:允許我們使用稱(chēng)為“HTML 流”的接口訪問(wèn)端對(duì) peer connection 內(nèi)部,以及允許訪問(wèn)瀏覽器中的編解碼器的接口。再加上諸如 Web Assembly 和 workers threads 的新技術(shù),你可以在瀏覽器,以及集成的端對(duì)端連接中使用 Javascript 進(jìn)行實(shí)時(shí)處理。
如果看一下現(xiàn)在的 WebRTC 的內(nèi)部,你會(huì)發(fā)現(xiàn)媒體流就像是從網(wǎng)絡(luò)傳入時(shí)一樣被拆包(depacketized)。這里會(huì)有一些丟失或延遲的適配。因此,我們對(duì)此進(jìn)行了重構(gòu)。
另一方面, 攝像頭輸入或麥克風(fēng)輸入已經(jīng)經(jīng)過(guò)編解碼器如 Opus 或 VP8,去除了回聲。比特率已經(jīng)根據(jù)網(wǎng)絡(luò)情況進(jìn)行了適配,然后將其打包為 RTP 數(shù)據(jù)包并通過(guò)網(wǎng)絡(luò)發(fā)送。我們想做到在 WebRTC NV 中攔截該管道,所以要從媒體框架開(kāi)始。因此,我們希望能夠在媒體幀從網(wǎng)絡(luò)到達(dá)顯示器,以及從攝像機(jī)麥克風(fēng)到網(wǎng)絡(luò)回到媒體幀時(shí)對(duì)其進(jìn)行監(jiān)聽(tīng)。我們希望能夠更好地管理這些流。目前我們提出兩個(gè)流方案,也正是我致力研究的兩個(gè) API。

第一個(gè)是可插入媒體流(Insertable Media Stream)。當(dāng)前的 Chrome 瀏覽器 86 中已提供此功能。Google 服務(wù)和其他外部服務(wù)已使用了此功能。你可以使用它來(lái)實(shí)現(xiàn)端到端加密,或者可以使用它向框架中添加自定義元數(shù)據(jù)(meta-data)。你要做的是在 PeerConnection 中定義此編碼的可插入媒體流,并且你也可以創(chuàng)建流。之后,當(dāng)你從攝像頭獲取視頻幀時(shí),它首先被編碼,比如 VP8 格式,之后你可以訪問(wèn)它并進(jìn)行流式處理。你還可以對(duì)其進(jìn)行加密或標(biāo)記其中一些元數(shù)據(jù)。
另一個(gè)是原始媒體流 API(Raw Media Stream)。這是標(biāo)準(zhǔn)委員會(huì)正在討論的標(biāo)準(zhǔn)工作。目前已經(jīng)有一些確切的建議了。從 Google 的角度來(lái)說(shuō),我們正在嘗試這種實(shí)現(xiàn)。該 API 允許我們?cè)L問(wèn)原始幀。它意味著,當(dāng)原始幀從攝像頭采集后,在還未進(jìn)行視頻編碼前,你就可以訪問(wèn)這些數(shù)據(jù)了。然后你可以對(duì)其進(jìn)行處理,比如實(shí)現(xiàn) AR 效果。你還可以運(yùn)行多個(gè)濾鏡來(lái)刪除背景,然后應(yīng)用一些效果。比如我想把我現(xiàn)在的視頻背景設(shè)成一個(gè)熱帶島嶼。這還可以應(yīng)用到自定義的編解碼器中,比如你此前使用的一些編解碼器與現(xiàn)在的瀏覽器不兼容,那么你可以利用這個(gè)接口將數(shù)據(jù)直接傳給編解碼器來(lái)處理。原始媒體流 API 可以提供一種非常有效的方式來(lái)訪問(wèn)此原始媒體。
總結(jié)一下。雖然 WebRTC 作為 W3C 正式標(biāo)準(zhǔn)已經(jīng)發(fā)布,但仍在繼續(xù)改進(jìn)。新的視頻編解碼器 AV1 可節(jié)省多達(dá) 50% 的帶寬,正在 WebRTC 和網(wǎng)絡(luò)瀏覽器中使用。開(kāi)源代碼的持續(xù)改進(jìn)有望進(jìn)一步減少延遲,提高視頻流的質(zhì)量。WebRTC NV 收集了創(chuàng)建補(bǔ)充 API 的倡議,以實(shí)現(xiàn)新的用例。這些 API 包括對(duì)現(xiàn)有 API 的擴(kuò)展,以提供更多對(duì)現(xiàn)有功能的控制,例如可擴(kuò)展視頻編碼,以及提供對(duì) low-level 組件的訪問(wèn)的 API。后者通過(guò)集成高性能的定制 WebAssembly 組件,為網(wǎng)絡(luò)開(kāi)發(fā)者提供了更多的創(chuàng)新靈活性。隨著新興的 5G 網(wǎng)絡(luò)和對(duì)更多交互式服務(wù)的需求,我們預(yù)計(jì)在未來(lái)一年內(nèi),持續(xù)增強(qiáng)在 WebRTC 的服務(wù)端建設(shè)。