技术实践 | Web 端实现 RTC 视频特效的解决方案
導(dǎo)讀:Web 是否真的無法享受到原生那樣高效豐富的視頻處理?是否有我們未知的黑科技能提升 Web 的 RTC 使用體驗(yàn)?我們決定針對 Windows 的瀏覽器來展開一番探究。
文|金杰
網(wǎng)易云信客戶端開發(fā)工程師
需求
隨著 RTC 技術(shù)的發(fā)展,音視頻通訊的門檻降到了一個(gè)極低的標(biāo)準(zhǔn)。移動(dòng)端、PC 端、Web 端、小程序,隨手拿起一個(gè)設(shè)備就可以完成高質(zhì)量的音視頻通話。而且伴隨著移動(dòng)互聯(lián)網(wǎng)的發(fā)展(4G,5G),AI 技術(shù)的演進(jìn),人們對于音視頻通訊的需求不再停留在聽得見看得到,而是開始追求更多交互新穎的通訊方式,如美顏、道具、互動(dòng)涂鴉等等。音視頻通訊方向的拓展層出不窮,尤其在 ToC 的場景。
從技術(shù)的角度來講,原生的視頻處理技術(shù)已經(jīng)并不稀奇。很多類似于 OpenCV 這樣的庫早已將自己的人臉捕捉,圖像處理等能力開源,新建一個(gè)工程調(diào)用不多的接口就可以實(shí)現(xiàn)一些簡單的視頻處理。然而?Web 端在這一塊卻始終落后原生,再厲害的前端技術(shù)在鼓吹性能的時(shí)候都只敢說接近原生,其瓶頸在此可見一斑(JavaScript 的設(shè)計(jì)初衷并不是運(yùn)行速度)。
技術(shù)選型
?ActiveX 方案?
2000年左右,微軟為了打敗當(dāng)時(shí)崛起的新興瀏覽器 Netscape,希望研發(fā)一個(gè)方案可以讓自己的龍頭產(chǎn)品 office 在 IE 上運(yùn)行,這便是 ActiveX 技術(shù)。聽起來很夢幻的一項(xiàng)技術(shù)原生與瀏覽器的無縫交互。ActiveX 與 Office 的結(jié)合最終也確實(shí)遏制了 Netscape 的發(fā)展,讓 IE 瀏覽器在很長一段時(shí)間霸占著主流的地位。
ActiveX 實(shí)際就是一個(gè)基于 COM 標(biāo)準(zhǔn)開發(fā)的 COM 組件,其通過在安裝的時(shí)候?qū)⒆约旱?GUID 配合安裝路徑寫入到注冊表中,JavaScript 可以輕松通過 GUID 來加載到這個(gè)原生對象并通過簡單的點(diǎn)語法完成調(diào)用。由于是 COM 組件,接口調(diào)用居然是直接在內(nèi)存間進(jìn)行,與原生工程調(diào)用動(dòng)態(tài)庫(DLL)無異。更離譜的是,ActiveX 支持原生的 UserControl 直接渲染在瀏覽器。MFC、QT、winform、WPF,主流的 Windows 界面開發(fā)框架都可以完成 ActiveX 的開發(fā)。(不得不承認(rèn),隨著移動(dòng)互聯(lián)網(wǎng)的蓬勃發(fā)展,PC 上的開發(fā)技術(shù)開始式微了,這些名詞遠(yuǎn)沒有 flutter、vue 等名詞來得耳熟能詳)。在使用 WPF 完成了一個(gè) ActiveX 插件的開發(fā)調(diào)用后我們大受震撼。就是這樣一個(gè)聽起來無所不能的方案,為什么就變得如此冷門?答案是:安全性。
由于 ActiveX 的高權(quán)限,高靈活性,使得它可以在用戶的 PC 上“為所欲為”。肆意操作新增或修改本地文件內(nèi)容、訪問登錄信息、在瀏覽器中直接運(yùn)行外部可執(zhí)行文件等,光聽這些就讓人覺得毛骨悚然。在21世紀(jì)初,互聯(lián)網(wǎng)剛剛興起的年代,大家普遍沒搞明白計(jì)算機(jī)、互聯(lián)網(wǎng)是什么的年代,不知道有多少游戲賬號就因?yàn)橛脩酎c(diǎn)擊了允許加載 ActiveX 插件而被盜。
所以?Chrome、Firefox 等瀏覽器開始逐漸拋棄對 ActiveX 的支持,就連微軟自己也在 Edge 中不再支持 ActiveX?,只有年老失修的 IE 還在頑強(qiáng)支持。然而可惜的是,IE 瀏覽器也已經(jīng)停止維護(hù),而且即將退出 Windows 系統(tǒng)預(yù)裝的名單。大勢所趨,ActiveX 的方案也注定被淹沒在技術(shù)發(fā)展的潮流中。
ActiveX 很好,尤其是銀行、政府等使用私有網(wǎng)絡(luò)的單位,ActiveX 的安全性問題對他們來說似乎不那么致命。然而我們不可能針對一個(gè)將死的技術(shù)來進(jìn)行我們的新方案設(shè)計(jì),或者說 ActiveX 會(huì)是我們特定場景下的備選方案,但永遠(yuǎn)不可能成為我們的首選。
?WebAssembly 方案?
隨著 ActiveX 的沒落,急需有一個(gè)新的方案來補(bǔ)充原生與前端交互的需求,此時(shí)?WebAssembly?應(yīng)運(yùn)而生。
通過 Emscripten 即可將 C、C++、Rust 代碼編譯為 WebAssembly,編譯獲得的 .wasm 文件為一種可被 JavaScript 調(diào)用的字節(jié)碼。
看到這些,這個(gè)方案是令人期待的,于是我們動(dòng)手來搭建自己的 WebAssembly。目前比較成熟的支持 WebAssembly 框架有 Unity、QT 等,Unity 與 QT 編譯 WebAssembly 的過程都很簡單,可以輕易搭建出測試 Demo,且原生的界面也很好地渲染到了前端,不禁讓我想起 ActiveX 曾經(jīng)的榮光!
接下來讓我們來調(diào)起攝像頭并做些簡單的視頻處理吧。滿懷期待寫好代碼,嘗試在前端運(yùn)行,無法完成。看了一眼 QT WebAssembly 的官網(wǎng):
QtMultimedia 框架已經(jīng)被確定無法在 WebAssembly 使用,連他們自身都還沒搞清楚哪些 Module 可用哪些不可用,在我們看來前路有數(shù)不清的“坑”。
為了保證安全性,WebAssembly 運(yùn)行在沙盒環(huán)境,其權(quán)限必然受限。我們開玩笑地聊到,對于開發(fā)者而言 WebAssembly 相對于 ActiveX 都像是一種退步(對用戶無疑是進(jìn)步)。
本著科學(xué)嚴(yán)謹(jǐn)?shù)膽B(tài)度,我們決定另辟蹊徑將這個(gè)方案驗(yàn)證到底,由前端采集視頻,WebAssembly 做處理,以此來驗(yàn)證其最終的可行性,以及網(wǎng)上所吹噓的接近原生的運(yùn)行速度。
幸運(yùn)的是 OpenCV 提供了 WebAssembly 的版本,正好可以供我們做一些簡單驗(yàn)證。搭建原生工程,集成 OpenCV 的 C++ 版本,而 WebAssembly 版本的 OpenCV 其官方已經(jīng)提供了測試地址,幫我們節(jié)省了不少工作。
以雙邊濾波為例,選取一組合適參數(shù)進(jìn)行對比驗(yàn)證,diameter 選取15,sigma 選取30。
WebAssembly 的表現(xiàn)如下:
視頻的幀率已經(jīng)下降到了 4FPS(上下浮動(dòng)),觀感已有明顯卡頓。
原生上的表現(xiàn)如下:
視頻的幀率依然保持 16FPS(上下浮動(dòng)),雖然體驗(yàn)有所影響,但是該值依然滿足 RTC 傳輸要求(RTC 傳輸一般視 13~30FPS 為正常)。
繼續(xù)在原生上添加高斯濾波處理,選取高斯核長寬各為3,表現(xiàn)如下:
視頻的幀率依然保持在 14FPS(上下浮動(dòng)),對性能影響可忽略,依然滿足 RTC 傳輸要求(RTC 傳輸一般視 13~30FPS 為正常)。
其他參數(shù)的表現(xiàn)大致與這組測試相同,起碼在特殊場景的視頻處理中 WebAssembly 的性能是遠(yuǎn)低于原生。當(dāng)然可能是 OpenCV 對 WebAssembly 的支持還不夠好,但是這組對比以及 WebAssembly 的權(quán)限支持已經(jīng)讓我們對其有些失望。
?WebSocket 本地連接方案?
這個(gè)方案并無系統(tǒng)的定義,其實(shí)現(xiàn)思路為以原生工程為 Server,前端通過 localhost 的端口與其交互,數(shù)據(jù)量小的可以用 HTTP(支持的瀏覽器更廣),數(shù)據(jù)量大的可以用 WebSocket(IE10以上)。對于 RTC,如果發(fā)送在前端,則 WebSocket 可能需要承擔(dān)每秒數(shù)M的數(shù)據(jù)傳輸來將視頻幀從原生進(jìn)程發(fā)送到前端,前端還需要通過 WebGL 進(jìn)行渲染。
雖然是在本地通信,但溢出的采集幀率以及音視頻在兩個(gè)進(jìn)程采集所可能導(dǎo)致的音畫同步問題都讓我們對其的表現(xiàn)表示擔(dān)憂,所以并未有過多嘗試。
?虛擬攝像頭方案?
多個(gè)方案都行不通,讓我們對 ActiveX 念念不忘。COM 在性能上有著其他方案所不具備的巨大優(yōu)勢,其他方案或是性能不如原生或是鼓吹性能接近原生,而 COM 則是實(shí)實(shí)在在的原生性能。
圍繞 COM 進(jìn)行一番調(diào)研,我們發(fā)現(xiàn)還有其他路徑可以滿足我們的需求,即?COM 組件結(jié)合 DirectShow 來將視頻發(fā)送到模擬攝像頭,從而在采集層面完成偷天換日!如果這個(gè)方案可行,那么最終的產(chǎn)品將不僅可以用于我們眼下的場景,所有使用 DirectShow 進(jìn)行攝像頭調(diào)用的應(yīng)用都將可以使用我們封裝的視頻處理技術(shù)。
搭建 COM 工程,封裝 AI 數(shù)字人形象的實(shí)現(xiàn),調(diào)用 DirectShow 接口完成虛擬攝像頭注冊與視頻流傳遞,編寫批處理腳本將我們的 COM 注冊到系統(tǒng)路徑。完成一系列工作,使用諸多攝像頭測試工具進(jìn)行測試,效果出奇的好。
以下為使用 AR 面具處理后的虛擬攝像頭接入網(wǎng)易會(huì)議的效果:
最終方案
經(jīng)過大量的方案驗(yàn)證,我們決定以虛擬攝像頭的方案作為我們最終的方案,無論從性能還是耦合性來說,這個(gè)方案都是無可挑剔。
?方案結(jié)構(gòu)?
?關(guān)鍵實(shí)現(xiàn)?
1.?首先我們新建一個(gè)動(dòng)態(tài)庫工程命名 WebCamCOM,并使用 CoCreateInstance 與 RegisterFilter 等接口將我們的對象注冊為 DirectShow Filter。
2.?借助 memoryapi.h 的接口來傳遞我們定義的數(shù)據(jù),此處我們除了傳遞基本的視頻數(shù)據(jù)之外還額外傳遞了視頻長寬與時(shí)間戳的信息。
3.?通過使用 CreateMutex 來保證內(nèi)存共享時(shí)的訪問安全。
4.?新建另一個(gè)動(dòng)態(tài)庫工程命名 SharedImageWrapper,對外只定義一個(gè)接口。
5.?根據(jù) shouldRotate 入?yún)頉Q定是否需要做垂直方向的翻轉(zhuǎn)(用于適配 Unity)。
6.?簡單處理 data 之后同樣通過 memoryapi.h 接口往我們定義好的 DirectShow Filter 傳遞視頻數(shù)據(jù)。
7.?上層集成 SendImage 接口即可以將采集的 RGB 數(shù)據(jù)發(fā)送至 DirectShow。
8.?編寫批處理腳本,使用 regsvr32 命令以管理員權(quán)限將 WebCamCom 注冊至系統(tǒng)注冊表。
?問題?
1. Unity 對 Texture 的采集自下而上,直接使用其 data 會(huì)有上下顛倒的現(xiàn)象,故需要做一次垂直翻轉(zhuǎn)。
2. Unity 可選 OpenGL 渲染與 Direct3D 渲染,兩種渲染方式的 Texture 句柄解析需要用兩套接口。
OpenGL:
D3D:
展望
DirectShow 雖然是目前主流的操作攝像頭的框架,但是 Media Foundation 框架的使用已經(jīng)成為趨勢,考慮未來將接口適配到 Media Foundation 框架(基于 USB 攝像頭驅(qū)動(dòng)開發(fā)也是一個(gè)可行的方案)。
目前視頻處理所支持的能力主要還是圍繞數(shù)字人形象、美顏、虛擬背景,基于現(xiàn)有的框架其實(shí)可以結(jié)合更多好玩的視頻處理技術(shù)進(jìn)來。
插件本身可以結(jié)合 WebSocket(HTTP)的方案來開放一些接口,諸如美顏參數(shù)、數(shù)字人形象的外形,這樣前端可以默默完成對插件的配置。
插件可以整合出實(shí)用的設(shè)置界面,可通過拖拖拽拽查看預(yù)覽效果。
總結(jié)
本文介紹了網(wǎng)易在 PC Web 端視頻處理方案上的一些探究,從多個(gè)方面對比了一些可選方案的優(yōu)劣,最終在虛擬攝像頭方案上大致闡述了實(shí)現(xiàn)思路。也許您不從事音視頻領(lǐng)域的開發(fā),也許您對 PC 開發(fā)不以為意,希望本文可以給您一些不一樣的角度去認(rèn)識這些技術(shù)。受限于篇幅,未對核心的 COM 組件機(jī)制做詳細(xì)介紹略有遺憾,大家如有興趣也可逆潮流來玩轉(zhuǎn)一下 PC 開發(fā)中的黑科技。
?作者介紹?
金杰,網(wǎng)易云信客戶端開發(fā)工程師,從事音視頻能力及IM能力場景化開發(fā)五年有余,偏愛移動(dòng)端開發(fā),PC 端開發(fā)也有涉及。
?相關(guān)閱讀推薦?
技術(shù)干貨 | JavaScript 之事件循環(huán)(Event Loop)
從0搭建在線聊天室,只需4步!
技術(shù)系列課回顧 | 網(wǎng)易云信變聲技術(shù)之變調(diào)不變速算法
總結(jié)
以上是生活随笔為你收集整理的技术实践 | Web 端实现 RTC 视频特效的解决方案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 干货回顾 | 泛娱乐社交 APP 出海的
- 下一篇: 云信小课堂|搭建应用级别在线聊天室,7步