給大家科普一下哈爾濱紅旗休閑娛樂(2022已更新(今日/知乎)
發(fā)了一篇抖音直播技術(shù)原理解析的純技術(shù)文章,發(fā)出去沒 1 分鐘直接被刪,賬號也被封,并且我的文章也找不到了,客服說無法提供我的文章備份,到底哪違規(guī)了也不說,就叫我理解,然后我發(fā) 10 幾條消息過去,直接就不理我了。以后再也不在這上發(fā)東西了,后續(xù)文章發(fā)在公眾號:羽月技術(shù),和 github:https://github.com/oyuyue/blog 上
斗魚直播相信大家都聽說過,打開斗魚官網(wǎng)就可以直接在瀏覽器中觀看直播。那么斗魚是如何實(shí)現(xiàn)瀏覽器視頻直播的呢?本篇文章就來解析斗魚是如何實(shí)現(xiàn)直播的,以及它是如何節(jié)省 80% 的 CDN 流量,要知道視頻直播流量費(fèi)并不便宜,斗魚每個月光這些流量費(fèi)都要支付幾個億,節(jié)省 CDN 流量就是省錢。
直播技術(shù)方案
在實(shí)際去斗魚直播間調(diào)試視頻直播之前,我就猜它肯定是使用 HTTP-FLV 方案來實(shí)現(xiàn)視頻直播,因?yàn)閲鴥?nèi)幾乎所有直播平臺都是使用 HTTP-FLV 方案。
但是去斗魚直播間并沒有找到 .flv 的網(wǎng)絡(luò)請求,而是找到了 .xs 的網(wǎng)絡(luò)請求,如下圖所示。

不過 .xs 網(wǎng)絡(luò)請求的響應(yīng)的 Content-Type 是 video/x-flv,原來只是后綴不同,看來我猜的果真沒錯,斗魚就是用的 HTTP-FLV。
HTTP+P2P FLV 拉流
不過為什么后綴是 .xs 而不是 .flv 呢?其實(shí)這里是因?yàn)槎肤~默認(rèn)并不完全使用 HTTP 去拉流,而是采用 CDN 和 P2P 兩種方式同時去拉流,.xs 并不是一個完整的 FLV 流,而是一個子 FLV 流。
進(jìn)入斗魚直播間,斗魚首先會去請求一個完整的 FLV 流,等 P2P 連接好了再去切換成子流。這是因?yàn)?P2P 連接比較慢,如果走來就走 P2P,那么視頻起播速度會非常慢。

上圖中第二個連接就是一個完整的 FLV 流,等 P2P 連接成功后會斷開連接去拉子流。
在 P2P 連接成功后,還可以在網(wǎng)絡(luò)面板看到一個 WebSocket 連接,如下圖所示,它是斗魚用來推送其他正在觀看當(dāng)前流的用戶的,這樣播放器就可以直接從推送的用戶這里拉流。

斗魚 P2P 是基于 WebRTC 的 DataChannel,可以打開 chrome 的 WebRTC 的調(diào)試頁面,可以看到有很多 WebRTC 連接,它可以接收其他用戶分享的視頻數(shù)據(jù),自己也會共享當(dāng)前下載到的視頻數(shù)據(jù)給其他用戶。

斗魚將一個完整的直播流進(jìn)行切片,分成一個個小的視頻分片并進(jìn)行編號(這樣方便用戶之間共享)然后將這些小分片分為多個子流,通過 HTTP 從 CDN 拉一路子流,然后通過 P2P 去其他用戶那里拉其他的子流。
但是通過 P2P 從其他用戶那里拉流并不是很穩(wěn)定,例如其他用戶可以能退出了直播間,或者網(wǎng)絡(luò)出了問題,這樣就會導(dǎo)致接收它分享的用戶直播斷流。為了提升直播穩(wěn)定性,如果在一定時間內(nèi)沒有收到其他用戶分享的數(shù)據(jù),斗魚播放器就會立刻從 CDN 去拉對應(yīng)的子流,并且 WebSocket 也會推薦新的用戶給播放器。
可以發(fā)現(xiàn),加上 P2P 拉流,大大增加了直播的復(fù)雜度。但是它帶來的好處也非常的明顯,就是可以省錢,省到就是賺到!因?yàn)榱髁抠M(fèi)非常的貴,斗魚每個月光直播帶寬都得花好幾個億。利用 P2P 從其他用戶那里拉流可以節(jié)省大量流量,例如一個直播流分為兩個子流,一個從 CDN 拉,一個從其他用戶那里拉,這樣理論上就可以節(jié)省 50% 的流量,而斗魚將一個直播流分成 6 個子流,一個從 CDN 拉,其余 5 個全部從其他用戶那里拉,理論上可以節(jié)省超過 80% 的直播流量!
當(dāng)然 P2P 拉流也有一些缺點(diǎn),例如直播延遲較高,不適用于低延遲直播場景,對用戶電腦和帶寬有一定消耗,因?yàn)槌藦钠渌脩裟抢锢?,?dāng)前用戶自己還要上傳視頻數(shù)據(jù)給其他用戶。
如果你想關(guān)閉 P2P,也比較簡單,可以在網(wǎng)絡(luò)面板屏蔽下圖中的地址即可。

屏蔽之后,斗魚就只會從 CDN 拉流,不走 P2P,如下圖所示,可以發(fā)現(xiàn)流的地址變成正常的 .flv 后綴。

無論是只使用 HTTP,還是使用 HTTP + P2P,它們的最終目的是獲取 FLV 視頻數(shù)據(jù)。
FLV 格式
FLV 視頻格式是由 Adobe 公司開發(fā),在 2003 年發(fā)布,用于視頻文件在網(wǎng)絡(luò)上傳輸。在 Flash 時代幾乎所有流媒體平臺都在使用 FLV 格式,但是隨著 Flash 技術(shù)的淘汰,F(xiàn)LV 也跟著沒落了,目前國外已經(jīng)沒有流媒體平臺在使用 FLV 了,但是在國內(nèi) FLV 卻廣泛用于網(wǎng)絡(luò)直播場景。
不像 Flash,H5 的 video 元素是無法播放 FLV 視頻的,我們需要借助 MSE 來自己控制視頻播放,具體原理是將 FLV 轉(zhuǎn)封裝成 FMP4 視頻格式,然后交給 MSE 播放即可。
MSE 全稱是 Media Source Extensions API,它是 Web 流媒體的基礎(chǔ),所有 Web 流媒體平臺最終都會用到它,如果對它感興趣,歡迎查看 流媒體視頻基礎(chǔ) MSE 入門 & FFmpeg 制作視頻預(yù)覽縮略圖和 fmp4目前有開源的 flv.js 來幫我們完成這件事,查看斗魚 dist 后代碼,斗魚也是使用的 flv.js,不過在之上加了很多自定義的代碼,例如加上了 h265 編碼的支持,flv.js 是不支持 h265 編碼的,F(xiàn)LV 官方規(guī)范也不支持,但是業(yè)務(wù)又有這種需求,所以一般將 FLV 視頻編碼 ID 等于 12 當(dāng)作 h265 的流。在斗魚直播中如果發(fā)現(xiàn)直播流是 h265 編碼并且瀏覽器不支持 h265,斗魚會利用 WASM 來軟解播放視頻。
直播時移
對于賽事直播斗魚是支持直播時移的,如下圖所示。

但是這個播放器的進(jìn)度條體驗(yàn)不是很好,進(jìn)度條的高度只有 3px,鼠標(biāo)非要精準(zhǔn)的放上去,才能有 Hover 的效果,這是沒那么容易做到的。這里推薦個好用開源的播放器進(jìn)度條 ppbar,你可以把它集成到任何播放器中去,非常的好用。
斗魚直播時移是基于 HLS 的,如果點(diǎn)擊一下進(jìn)度條,斗魚播放器會黑一下,將 FLV 切換成 HLS。

在剛開始進(jìn)入直播間拉流的時候,斗魚播放器可以獲取到服務(wù)器返回的一個時間戳,單位是秒,當(dāng)用戶點(diǎn)擊進(jìn)度條跳轉(zhuǎn)到前 10 分鐘時,就直接用當(dāng)前時間減去 600 秒就得到了前 10 分鐘視頻的時間戳,然后會用這個時間戳去請求請求一個 getVodStream 接口獲取到 HLS 時移流地址,獲取到 HLS 過后,就和普通 HLS 直播一樣去播放即可。
和 FLV 一樣,要在瀏覽器中播放 HLS 流,同樣需要 MSE API 來播放,目前可以借助開源的 hls.js 來在瀏覽器中播放 HLS 流。查看斗魚 dist 過后的代碼,斗魚應(yīng)該沒有使用 hls.js,而是自己實(shí)現(xiàn)在瀏覽器中播放 HLS。
總結(jié)
這篇文章介紹了斗魚 H5 直播技術(shù)的原理,斗魚不僅使用國內(nèi)常用的 HTTP-FLV 方案,還加入了 P2P 拉流,從而節(jié)省 CDN 流量。對于賽事直播,斗魚還支持直播時移,直播時移是使用 HLS 來實(shí)現(xiàn)的,用戶在 seek 后會通過 seek 到的時間點(diǎn)去服務(wù)器換取對應(yīng)的時移 HLS 流地址,然后走 HLS 拉流即可。
更多
CSS3 transform 和 canvas 背后不為人知的秘密這么炫酷可交互的網(wǎng)站,居然沒有一行 JS 代碼!NPlayer 支持任何流媒體和 B 站彈幕體驗(yàn)的視頻播放器流媒體視頻基礎(chǔ) MSE 入門 & FFmpeg 制作視頻預(yù)覽縮略圖和 fmp4原來愛優(yōu)騰等視頻網(wǎng)站都是用這個來播放流媒體的3 秒左右的低延遲直播方案 - LHLS 和 LL-HLSLL-DASH CMAF 低延遲直播掃描二維碼推送至手機(jī)訪問。
版權(quán)聲明:本文由財神資訊-領(lǐng)先的體育資訊互動媒體轉(zhuǎn)載發(fā)布,如需刪除請聯(lián)系。