由白玉蘭開源開放研究院指導,聯合掌門教育、聲網、vue北京,舉辦的第二期前端技術分享活動,已於6.19號落幕,如下爲大咖講師們,現場演講的整理稿,感謝你們的支持:前端
分享嘉賓——李順博,Web引擎開發高級工程師,如下爲李順博同窗精彩演講的部份內容:vue
目前,針對WebRTC來講,最大的問題就是使用體驗不理想,常常卡頓,主要問題咱們能夠簡單從下面三點分析:node
Web平臺碎片化嚴重。WebRTC官方正式標準一直到最近兩年才被肯定下來,並且標準的迭代很是迅速,好比國外的chrome、Firefox,國內的360瀏覽器、QQ瀏覽器等等,都有基於本身想法上的可選性實現。web
WebRTC實現細節不可控。對於不少Web的開發者而言,咱們每每比較關注的是Media、Vedio這些HTML5標籤自己,但好比我要想控制裏面的一些網絡傳輸FEC、弱網對抗、帶寬估計、優先級保障等算法、使用特殊的編碼解碼,依賴純Web是作不到的,這不是瀏覽器的使命,若是想要作這種更底層的控制,就只能要想其餘辦法參與到裏面去。算法
計算密集型算法可選項少。咱們不少時候須要對視頻進行一些預處理的動做,好比美顏功能,如今通用的作法是首先須要獲取到用戶本地的一些原始的視頻採集數據,而後繪製到canvas上,經過canvas接口獲取到imagedata,將imagedata傳遞到Web Assembly,而後再對它進行進一步的算法運算,好比磨皮、提亮等等這些操做,而後從新繪製到canvas裏面,這個過程鏈路自己比較長。還有一點就是Web Assembly技術自己,也是一直在不停發展,他自己有本身的限制,好比Web Assembly的實現是基於chrome自己的一個render主線程驅動。雖而後續出現了Web worker的工做線程實現以及並行計算等,可是執行性能也不是特別好,若是咱們但願可以充分利用的計算資源,在這種狀況下就很難實現。chrome
另外,對於GPU部分,WebGl實現的細節上是有側重點的,由於瀏覽器WEB自己是要面向整個標籤頁的渲染,而不只是視頻窗口這一小塊,因此相比專業的視頻渲染性能方面的表現並不太好。canvas
在最開始咱們作技術評估的時候,可選框架有幾大類,Electron、CEF、Qt等等,但不少的開發框架,像CEF和Qt基礎技術棧比較偏向C、C++、Java等等,開發習慣和生態上和咱們前端開發體驗不一致,尤爲是它的開發工具鏈是須要獨立構建,因此最終咱們選擇了Electorn,它是基於Nodejs的一個技術方案,前端在開發的時候,咱們可使用熟悉的開發環境,好比說Npm、yarn,還有包括後續的測試打包等整個構建過程。小程序
對於原生擴展能力的注入,咱們將一些關鍵的業務邏輯的實現,經過用C++代碼放到V8引擎裏與原生能力結合起來的,後續經過bridge,將能力暴露給上層。這裏最大的問題在於每個V8引擎版本,底層C++的接口並不一致,而且,隨着nodejs版本的升級,每一個版本里面的接口實現也略微不一樣的,這也是長期以來讓社區比較詬病問題。這裏咱們的解決方案是,採用nodejs提供的node api實現,它是向後兼容的,以此來保持底層接口一致性,解決開發插件接口和node版本依賴的問題。api
當咱們的js層調用經過bridge注入到native後,驅動咱們另一個團隊開發的native SDK,包含了聲網主要的功能和算法,好比咱們的RTN網絡接入、AI降噪算法、背景分割、超分算法等等。另外從前端開發體驗上,用戶只須要改動少許的代碼,就能夠完成基於agora sdk ng開發的自有APP的適配,這也是咱們框架的初衷之一,保持外部開發用戶的體驗的基礎上,可以提高它裏面的應用能力。瀏覽器
音視頻應用的特色就是它的數據體積比較大,每一幀數據根據用戶視頻分辨率的不一樣,從幾K到幾十M都有可能,同時,咱們還必須對這些數據進行解碼、編碼等等操做,這就要求咱們可以去充分使用用戶本地的計算能力,這裏就涉及到子線程相關的調度操做,經過異步事件驅動,咱們能夠設計異步事件的隊列管理,原平生臺生產、主線程消費的模式。另外由於單個數據體積比較大,若是渲染線程和異步線程數據交互經過copy進行交互,內存開銷可想而知,這裏就必須使用到一些node api提供的external-ArrayBuffer技術,相似智能指針引用的解決方案,咱們只須要保證Buffer的生命週期便可,即在js層調用期間可用,指針銷燬時同時銷燬buffer,避免內存泄漏。
受限於網絡風暴等等問題,咱們用戶不少時候分辨率很難保持1080P不變,這個時候咱們就須要一些平衡算法,在幀率和分辨率之間作平衡,這種狀況下,視頻寬窄就有可能發生變化,那咱們就須要針對這種狀況作一些特殊處理,canvas是能夠經過更新texture的方式,適配視頻數據幀的寬高、步長等,而後經過CSS樣式控制總體頁面渲染比例及佈局便可,不須要再作重採樣來保證寬高比,這個作法也是和傳統原生視頻應用渲染方面有明顯差別的地方。
本地音頻採集完通常不須要本地回放,但在一些業務場景下,咱們的用戶但願可以根據本身的聲音反饋作一些特殊處理,好比用戶會但願能夠經過直觀的聽到本身的音量來調整麥克風的相對位置等等。並且這也算是咱們爲了可以保證與agora sdk ng這一致性功能。因爲瀏覽器音頻播放是異步執行的,即主線程將音頻數據轉發給音頻線程,音頻線程播放結束後通知主線程,主線程再處理下一個音頻數據段,這個過程自己是會有始終消耗的,因此在實時音頻播放場景中的直觀體驗就是,隨着時間增加,時延累加明顯,而且數據播放間隔出現有明顯噪音。
咱們的解決方案比較簡單直接,採用audio workletprocessor接口,由咱們來控制音頻傳遞給音頻播放線程的頻率,流式傳遞音頻數據到異步線程,這樣就避免線程間反饋形成的時延累加,聽起來會很順滑,加上每次數據段比較短,約10ms左右,用戶聽起來就感受本身的聲音變大了,沒有明顯的迴音感。
將來咱們但願可以把更多聲網nativeSDK能力暴露到上層應用中,好比咱們的桌面共享、AI降噪、美聲、vp9編碼解碼、背景分割、美顏、超分等等,咱們聲網內部已經進入到測試環節,後續也但願可以賦能給咱們的用戶更加方便、強大的Web應用開發能力。