斗魚直播相信大家都聽說過,打開斗魚官網就可以直接在瀏覽器中觀看直播,那么斗魚是如何實作瀏覽器視頻直播的呢?本篇文章就來決議斗魚是如何實作直播的,以及它是如何節省 80% 的 CDN 流量,要知道視頻直播流量費并不便宜,斗魚每個月光這些流量費都要支付幾個億,節省 CDN 流量就是省錢,
直播技術方案
在實際去斗魚直播間除錯視頻直播之前,我就猜它肯定是使用 HTTP-FLV 方案來實作視頻直播,因為國內幾乎所有直播平臺都是使用 HTTP-FLV 方案,
但是去斗魚直播間并沒有找到 .flv 的網路請求,而是找到了 .xs 的網路請求,如下圖所示,
不過 .xs 網路請求的回應的 Content-Type 是 video/x-flv,原來只是后綴不同,看來我猜的果真沒錯,斗魚就是用的 HTTP-FLV,
HTTP+P2P FLV 拉流
不過為什么后綴是 .xs 而不是 .flv 呢?其實這里是因為斗魚默認并不完全使用 HTTP 去拉流,而是采用 CDN 和 P2P 兩種方式同時去拉流,.xs 并不是一個完整的 FLV 流,而是一個子 FLV 流,
進入斗魚直播間,斗魚首先會去請求一個完整的 FLV 流,等 P2P 連接好了再去切換成子流,這是因為 P2P 連接比較慢,如果走來就走 P2P,那么視頻起播速度會非常慢,
上圖中第二個連接就是一個完整的 FLV 流,等 P2P 連接成功后會斷開連接去拉子流,
在 P2P 連接成功后,還可以在網路面板看到一個 WebSocket 連接,如下圖所示,它是斗魚用來推送其他正在觀看當前流的用戶的,這樣播放器就可以直接從推送的用戶這里拉流,
斗魚 P2P 是基于 WebRTC 的 DataChannel,可以打開 chrome 的 WebRTC 的除錯頁面,可以看到有很多 WebRTC 連接,它可以接收其他用戶分享的視頻資料,自己也會共享當前下載到的視頻資料給其他用戶,
斗魚將一個完整的直播流進行切片,分成一個個小的視頻分片并進行編號(這樣方便用戶之間共享)然后將這些小分片分為多個子流,通過 HTTP 從 CDN 拉一路子流,然后通過 P2P 去其他用戶那里拉其他的子流,
但是通過 P2P 從其他用戶那里拉流并不是很穩定,例如其他用戶可以能退出了直播間,或者網路出了問題,這樣就會導致接收它分享的用戶直播斷流,為了提升直播穩定性,如果在一定時間內沒有收到其他用戶分享的資料,斗魚播放器就會立刻從 CDN 去拉對應的子流,并且 WebSocket 也會推薦新的用戶給播放器,
可以發現,加上 P2P 拉流,大大增加了直播的復雜度,但是它帶來的好處也非常的明顯,就是可以省錢,省到就是賺到!因為流量費非常的貴,斗魚每個月光直播帶寬都得花好幾個億,利用 P2P 從其他用戶那里拉流可以節省大量流量,例如一個直播流分為兩個子流,一個從 CDN 拉,一個從其他用戶那里拉,這樣理論上就可以節省 50% 的流量,而斗魚將一個直播流分成 6 個子流,一個從 CDN 拉,其余 5 個全部從其他用戶那里拉,理論上可以節省超過 80% 的直播流量!
當然 P2P 拉流也有一些缺點,例如直播延遲較高,不適用于低延遲直播場景,對用戶電腦和帶寬有一定消耗,因為除了從其他用戶那里拉流,當前用戶自己還要上傳視頻資料給其他用戶,
如果你想關閉 P2P,也比較簡單,可以在網路面板屏蔽下圖中的地址即可,
屏蔽之后,斗魚就只會從 CDN 拉流,不走 P2P,如下圖所示,可以發現流的地址變成正常的 .flv 后綴,
無論是只使用 HTTP,還是使用 HTTP + P2P,它們的最終目的是獲取 FLV 視頻資料,
FLV 格式
FLV 視頻格式是由 Adobe 公司開發,在 2003 年發布,用于視頻檔案在網路上傳輸,在 Flash 時代幾乎所有流媒體平臺都在使用 FLV 格式,但是隨著 Flash 技術的淘汰,FLV 也跟著沒落了,目前國外已經沒有流媒體平臺在使用 FLV 了,但是在國內 FLV 卻廣泛用于網路直播場景,
不像 Flash,H5 的 video 元素是無法播放 FLV 視頻的,我們需要借助 MSE 來自己控制視頻播放,具體原理是將 FLV 轉封裝成 FMP4 視頻格式,然后交給 MSE 播放即可,
MSE 全稱是 Media Source Extensions API,它是 Web 流媒體的基礎,所有 Web 流媒體平臺最終都會用到它,如果對它感興趣,歡迎查看 流媒體視頻基礎 MSE 入門 & FFmpeg 制作視頻預覽縮略圖和 fmp4
目前有開源的 flv.js 來幫我們完成這件事,查看斗魚 dist 后代碼,斗魚也是使用的 flv.js,不過在之上加了很多自定義的代碼,例如加上了 h265 編碼的支持,flv.js 是不支持 h265 編碼的,FLV 官方規范也不支持,但是業務又有這種需求,所以一般將 FLV 視頻編碼 ID 等于 12 當作 h265 的流,在斗魚直播中如果發現直播流是 h265 編碼并且瀏覽器不支持 h265,斗魚會利用 WASM 來軟解播放視頻,
直播時移
對于賽事直播斗魚是支持直播時移的,如下圖所示,
但是這個播放器的進度條體驗不是很好,進度條的高度只有 3px,滑鼠非要精準的放上去,才能有 Hover 的效果,這是沒那么容易做到的,這里推薦個好用開源的播放器進度條 ppbar,你可以把它集成到任何播放器中去,非常的好用,
斗魚直播時移是基于 HLS 的,如果點擊一下進度條,斗魚播放器會黑一下,將 FLV 切換成 HLS,
在剛開始進入直播間拉流的時候,斗魚播放器可以獲取到服務器回傳的一個時間戳,單位是秒,當用戶點擊進度條跳轉到前 10 分鐘時,就直接用當前時間減去 600 秒就得到了前 10 分鐘視頻的時間戳,然后會用這個時間戳去請求請求一個 getVodStream 介面獲取到 HLS 時移流地址,獲取到 HLS 過后,就和普通 HLS 直播一樣去播放即可,
和 FLV 一樣,要在瀏覽器中播放 HLS 流,同樣需要 MSE API 來播放,目前可以借助開源的 hls.js 來在瀏覽器中播放 HLS 流,查看斗魚 dist 過后的代碼,斗魚應該沒有使用 hls.js,而是自己實作在瀏覽器中播放 HLS,
總結
這篇文章介紹了斗魚 H5 直播技術的原理,斗魚不僅使用國內常用的 HTTP-FLV 方案,還加入了 P2P 拉流,從而節省 CDN 流量,對于賽事直播,斗魚還支持直播時移,直播時移是使用 HLS 來實作的,用戶在 seek 后會通過 seek 到的時間點去服務器換取對應的時移 HLS 流地址,然后走 HLS 拉流即可,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/513070.html
標籤:JavaScript
下一篇:WebSocket
