更好用的 Web 端 H265 播放技術架構
作者簡介: 百度 CyberPlayer、雲端非線性編輯、音視頻工程師
h265web.js 作者 (https://github.com/numberwolf/h265web.js)
01 背景
隨着視頻內容的佔比逐步擴大,直播、點播內容越來越多;在此基礎上,視頻傳輸的帶寬成本也跟着上漲,降低成本爲第一要務,首先要考慮的就是增加視頻的壓縮率。而目前網絡上多爲 H.264 的視頻,若將網絡上的視頻壓縮爲 H.265,可以較 H.264 壓縮率更高、節省更多成本。
瀏覽器對編碼的支持
當前瀏覽器下我們常用的方式是 Video 標籤和 MSE 的方式來進行視頻播放,但是現階段的瀏覽器基本都只支持 H.264 的解碼和播放 (瀏覽器內部完成了解碼)。
對於原生對於 265 幾乎無支持能力,僅僅只有 Apple 的 Safari 瀏覽器的部分版本支持 H.265 解碼播放,但是根本無法滿足生產環境下的需求。
圖 1. 瀏覽器對於 H.265 播放的能力支持度
瀏覽器對於 MSE 的支持
下圖,爲瀏覽器對於 MSE 的支持程度,可見 MSE 支持也不是很普遍。
圖 2. 瀏覽器對於 MSE 的能力支持度
02 網頁 H265 播放架構
目前需要解決兩個問題:
-
網頁端的一個通用 H.265 視頻播放問題。
-
網頁端對於 MSE 不支持的問題解決方案。
一個播放器的組成部分
圖 3. 播放器的組成部分
-
視頻部分
對於 H.265 播放問題,我才用了 WebAssembly 的解決方案,通過 C/C++ 開發的解碼和解封裝模塊打包爲 wasm 文件。
如下圖,大部分瀏覽器都已經支持了 wasm。
圖 4. 瀏覽器對 wasm 的支持度
-
音頻部分
音頻部分,採用了 WebAudio 方式去進行音頻解碼和播放。
如下圖,大部分瀏覽器都已經支持了 webaudio。
圖 5. 瀏覽器對 Webaudio 的支持度
H265 播放詳細設計
- 整體設計
圖 6. H265 播放整體設計圖
主要分爲:
- Js-Demuxer/Wasm-Demuxer
解封裝器,分爲 JS 部分和 WASM(C/CPP) 部分實現,應對不同的 BOX。
2. Wasm-Decoder
解碼器,主要針對 265 幀的解碼。
- WebAudio-Player
音頻播放器,承擔了 AAC 音頻的播放,包括 Seek、Play、Pause 等行爲。
- 具體流程
* 根據視頻流 URL 尾綴
和 協議
進行初始化 BOX 判斷
* Fetch 獲取到視頻流媒體開始下載
* 下載 Chunk 輸入 Demuxer
進行 Probe
* 探測到具體的 Mediainfo
後,開始進行幀數據讀取
* 讀取到音視頻幀後餵給 Queue
* 視頻幀餵給 wasm-decoder
進行解碼,緩存一定的幀數據
* 視頻幀交給 OpenGL(WebGL) 進行渲染
* 音頻幀獲取 Body 數據,根據 samplerate 和 channel 等數據組合 ADTS 頭。(如下圖)
圖 7. 音頻幀獲取 Body 數據
* 音頻組包,ADTS 頭 + Body 組音頻包餵給 Webaudio 進行解碼播放。
- 難點
* WebAudio 不支持 push 隊列播放的方式,我才用了交叉上下文的形式解決了此播放問題。
* 視頻下載過程中可能會阻塞瀏覽器其它行爲,搶用資源,這部分需要才用 worker 異步下載的方式。
* 視頻 Seek 如何最快精準 Seek 操作,這部分我採用了類搜索引擎的方式,構建了多層幀索引進行檢索後精準 Seek。
效果
- 整體播放 Demo
圖 8. 播放器整體 Demo
- 性能
* 目前保守測試可以併發兩路 1m/s 的 720P HEVC 視頻播放。
* 支持 1 路 1080P 視頻播放。
- 能力
* 支持點播、直播
* 支持安防、點播、直播場景
03 心路歷程
起點
最初要寫 web 265 播放器的念頭始於去騰訊之前一段時間,之前也做過 Native 端的播放器;爲了深耕音視頻,當時回顧總結了一下自己的技術深度和廣度,想從 Web 端 265 播放器入手把 web 上的音視頻技術棧的廣度和深度進行補充。
之前也只是寫了一個 Demo 級別的掛在 Github,後來來了百度,纔開始正式在個人業餘時間開始維護起來,逐步引入生產環境,對外輸出。
研發那些事
其實整個研發歷程中,讓我懂得了,無論做任何事情,要 勇於重構
(建立在你對整體技術架構非常自信能 hold 住纔可以).
沒有一勞永逸,一成不變的產品設計和技術架構,你總要隨着用戶、時代的變化而變化;當然你也可以不去重構,而是堆砌,最終導致的結果就是:一個月不去維護的話,你可能 "看着鏡子裏的自己都感覺陌生"。
-
困難
-
整體項目都是一個人維護與研發,你的出發點建立在技術實驗上,但是後續用的人越來越多,開始考慮生產環境,你不得不重構,這注定是一個耗時且用戶無感知的 痛苦過程。
-
越來越多的 Feature 需求,你要做非常多的取捨,因爲
週末只有 2 天
,對於產品的設計、技術需求的取捨必須做精確的判斷;對標競品、確定你的用戶羣體是安防、短視頻、長視頻 或者是研發類用途,這部分的成本投入也佔了不少的比例。 -
社區用戶不看 README、喜歡私聊(不在羣裏提問)也會帶來很多困擾,會花費非常打的成本投入去打磨用戶。
-
做開源就要有做開源的覺悟,哪怕只有付出。
-
收穫
其實搞得開源項目不止這一個,只不過今天的主體是 265 播放器。
* 對於 Web 端 265 的播放器使用羣體有了一個清晰的認知和劃分,這部分對於日後的產品設計和迭代有非常大的幫助。
* 對於我個人而言,對於播放的音視頻技術場景和 Web 端的音視頻技術棧有了從前到後的完整認知 和 技術儲備(從 0-1 全部是我一個人完成的)。
* 結識了許多業內大佬朋友、還有前輩,生活也更加充實了。
* 這幾年開源產品、技術架構做了非常多,產品設計、交互設計、產品運營思維也是不知不覺的就培養了起來。
04 結語
播放器並非一個一勞永逸的事情,隨着時代的進步、場景的遞增,播放器也需要緊跟步伐。
百度 Cyberplayer 正在支持 HDR10 的播放開發(歡迎使用)。
作者的音視頻開源技術支持 QQ 羣: 925466059
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/QQeNOAdADg_e8CFq-muNxg