React Hooks高仿B站Web移動端直播

code_mcx發表於2019-05-05

前言

幾個月前React Hooks正式發版,在正式發版之前,釋出了alpha版本,這時就已經有很多人開始分享React Hooks的使用方式和經驗。筆者也是等到了正式發版穩定後才開始學習,這次在原來高仿B站視訊彈幕的基礎上使用Hooks開發了直播功能

Hooks

Hooks官方介紹說不用寫class元件就能使用state和其它class元件的特性,這簡直是Functional programming黨的福利,我們知道React中一個function就是一個元件,hooks的引入把React變得更加函式化

由於一些原因,才引入了Hooks,比如this關鍵字不同與其它語言,需要理解this在javascript中是如何工作的。事件處理的時候處理函式必須繫結this關鍵字或者需要宣告成類的屬性,這個語法目前還是不穩定的。class元件中componentDidMountcomponentDidUpdate可能都需要編寫資料抓取程式碼,那麼就需要寫兩份相同的程式碼,某些情況下需要在componentDidMount中設定事件監聽,在componentWillUnmount中移除事件監聽,相關連的程式碼被拆分,很容易出現bug

官方沒有打算移除class元件,不建議用hooks重寫class,而是推薦在新的程式碼中嘗試使用Hooks

想學習Hooks的童鞋可以到移步到官方文件(英文 中文)

class元件的方法和hooks對應如下

  • constructor:函式元件沒有,直接在函式體內使用useState初始化
  • getDerivedStateFromProps:在函式元件內使用useState儲存props,props變更時做相應的邏輯處理
  • shouldComponentUpdate:使用React.memo
  • render:函式元件本身
  • componentDidMount, componentDidUpdate, componentWillUnmount:useEffecthook包含了三個生命週期方法

在使用useEffect時,第二個引數很重要,傳入[],表示在元件mount時候回撥,元件update時不回撥,類似class元件中的componentDidMount。函式元件中的內部函式使用了propsstate,並且在useEffect回撥函式中呼叫,該函式一定要放到useEffect的回撥函式中定義,同時把使用的propsstate傳入第二個引數陣列中作為依賴。以下兩種情況可以在useEffect外部定義函式

  • 函式不依賴props或state
  • 函式是一個純函式,沒有副作用,沒有資料請求

class元件的setState方法用來更新state,它的第二個引數是一個回撥函式,在元件update後回撥,Hooks暫時沒有對應的替代方案,知道了元件更新時需要的時間後,可以用setTimeout進行hack

直播

近幾年來,直播非常火熱,主播用一臺電腦或手機不出門就能賺錢,看直播成為了年輕人的一種娛樂方式

做一個直播需要客戶端和服務端配合,客戶端錄製畫面,把視訊流推給伺服器,伺服器對視訊流進行轉碼,轉成各種格式的視訊流,在播放直播的時候,客戶端從服務端拉取直播流進行播放。某裡,某訊在直播這塊都有一整套的解決方案,只要花錢就很容易搭建起一套直播服務

常見的直播協議有RTMP、 HLS 和 FLV

  • RTMP 協議實時性高,常用來要求延時很短的視訊流,但出現卡頓的概率高
  • HLS 協議延時相對較大,但觀看體驗好,手機端天然支援
  • FLV 居於兩者之間,是延時和卡頓相對平衡的播放協議,國內使用者使用較多

這三種協議網上都有詳細的說明

各平臺支援情況如下

平臺 RTMP HLS FLV
Android 支援 支援 支援
IOS 支援 支援 支援
PC 支援(需要flash) 支援(video+hls.js) 支援(video+flv.js)
移動端(Android) 不支援 android4.0+ 不支援
移動端(IOS) 不支援 支援 不支援

Android和IOS上這三種都支援

移動端對HLS天然支援,最好的選擇

PC web端不支援video需要用flash播放,支援video時可以用FLV或HLS,但video不支援flv格式,使用B站開源的flv.js就可以播放flv格式的直播流,它是通過將flv轉成mp4格式,再用Media Source Extensions API餵給video進行播放。hls.js實現了HLS協議的客戶端,它同樣需要video和Media Source Extensions API的支援,PC端暫不支援hls,如需播放hls流,就要用到hls.js。HLS延時性較大,在PC端播放直播時一般不採用,但是由於體驗好,在點播的時候優先採用HLS

還有一種基於HTTP的動態自適應流DASH,它通過一種自適應的位元率流技術,使高質量的流媒體可以通過 HTTP 協議進行傳輸,在播放時根據網路條件自動選擇位元速率進行播放。類似HSL,DASH將內容分割為一個或多個片段,每個片段包含很短長度的可播放內容,並且有一個媒體描述片段資訊(MPD檔案),它還支援多種編碼格式

本例中使用的是HLS直播流,很多直播網站的移動端在pc瀏覽器上除錯無法播放,這裡筆者使用了hls.js,在pc上同樣也可以播放HLS流(Chrome 70及以上會有net::ERR_CERT_SYMANTEC_LEGACY錯誤),想在chrome上觀看hls直播流請看下面一段

另外筆者高仿了一個直播網站PC端,使用了FLV直播流,在支援video和Media Source Extensions API的瀏覽器上都可以進行播放,戳這裡,對應的移動端戳這裡,使用的是HLS直播流

預覽

預覽地址:barrage.codemcx.work/live

二維碼:

React Hooks高仿B站Web移動端直播

原始碼

Github

Hooks相關程式碼在src/views/live目錄下

覺得不錯給個Star,謝謝啦~

相關文章