網頁中的直播

以前的工做一直是在負責公司直播產品的網頁前端開發,本文是對網頁直播的一個總結。下面我會以直播協議爲基礎,以及各個協議在PC、H5(這裏指手機網頁)的表現來進行總結。javascript

網頁直播經常使用到的流媒體協議有RTMP、HDL(HTTP-FLV)、HLS這3種。css

RTMP

實時消息協議(英語:Real-Time Messaging Protocol,縮寫RTMP)也稱實時消息傳輸協議,是最初由Macromedia爲經過互聯網在Flash播放器與一個服務器之間傳輸流媒體音頻、視頻和數據而開發的一個專有協議。Macromedia後被Adobe Systems收購,該協議也已發佈了不完整的規範供公衆使用。wikihtml

RTMP協議的延遲較低,通常都在3s左右。前端

在移動端的web端是徹底不支持播放RTMP的直播流的。java

在pc端只能在基於flash的播放器上播放。pc網頁上支持rtmp協議的播放器還很多,好比video.js+falsh plugin、百度的cyberplayer、騰訊的TCPlayerLitejwplayergit

雖然這樣,都是因爲其低延遲的特色,而且RTMP 協議爲流媒體而設計,在推流(obs推流)中用的比較多,同時大多 CDN 廠商支持RTMP 協議,因此目前國內的不少直播產品都會使用這種直播協議,咱們在pc網頁上的直播也是rtmp的協議的。github

RTMP 直播示例代碼
使用video.jsvideojs-flash播放rtmp直播流,手機不支持web

<video id="rtmp_player" width="600" height="400" controls class="video-js vjs-default-skin">
  <source src="rtmp://58.200.131.2:1935/livetv/hunantv" /> </video>
<script src="//cdn.bootcss.com/video.js/7.6.0/alt/video.core.min.js"></script>
<script src="//cdn.bootcss.com/videojs-flash/2.2.0/videojs-flash.min.js"></script>
<script>
  const player = videojs('rtmp_player', () => {
    console.log('rtmp player init complete');
  });
</script>
複製代碼

HDL(HTTP-FLV)

HTTP-FLV,即將音視頻數據封裝成FLV,而後經過HTTP協議傳輸給客戶端。它使用相似 RTMP流式的 HTTP 長鏈接,需由特定流媒體服務器分發的,兼顧二者的優勢。以及能夠複用現有 HTTP 分發資源的流式協議。它的實時性和 RTMP 相等,與 RTMP 相比又省去了部分協議交互時間(能夠比RTMP作到更低的延遲),首屏時間更短,可拓展的功能也更多。ajax

HTTP-FLV的延遲和RTMP差很少,能夠作到比RTMP更低一點。npm

在pc網頁端,咱們能夠經過flv.jsflv.js須要依賴一些瀏覽器新特性的,須要HTML5 VideoMSEWS)來播放HTTP-FLV的流。順便說一下flv.js的主要原理,在獲取到FLV格式的音視頻數據後經過原生的JS去解碼FLV數據,再經過MSEblob給原生HTML5 Video播放。一樣也能夠經過基於flash的播放器來兼容播放。(須要注意跨域,http/https混合使用等問題

遺憾的是因爲MSE在移動端的支持較差(目前只有安卓4.4.4以上支持,蘋果只有iPadOS 13支持can i use) ,因此HTTP-FLV直播在移動網頁上的使用也不多(蘋果大部分不支持就很悲傷)。

目前來說HTTP-FLV在pc端的使用仍是挺多的,由於它能夠脫離flash直接播放(flash太耗費性能了,特別是蘋果電腦上,看一下視頻風扇就呼呼的),例如鬥魚,咱們能夠打開他的網頁F12能夠看到video中的地址是blob:xxx這樣的形式,基本能夠判斷是基於flv.js或者其餘相似方案實現的。

鬥魚圖片

固然了b站也是的,畢竟flv.js就是b站開源的。

b站圖片

HTTP-FLV 直播示例代碼
使用flv.js播放

<video id="flv_player" width="600" height="400" controls></video>
<script src="//cdn.bootcss.com/flv.js/1.5.0/flv.min.js"></script>
<script>
  if (flvjs.isSupported()) {
    var flvVideo = document.getElementById('flv_player');
    var flvPlayer = flvjs.createPlayer({
      type: 'flv',
      url: 'http://cyberplayerplay.kaywang.cn/cyberplayer/demo201711-L1.flv'
    });
    flvPlayer.attachMediaElement(flvVideo);
    flvPlayer.load();
    flvPlayer.play();
  }
</script>
複製代碼

HLS

HTTP Live Streaming(縮寫是HLS)是一個由蘋果公司提出的基於HTTP的流媒體網絡傳輸協議。是蘋果公司QuickTime X和iPhone軟件系統的一部分。它的工做原理是把整個流分紅一個個小的基於HTTP的文件來下載,每次只下載一些。當媒體流正在播放時,客戶端能夠選擇從許多不一樣的備用源中以不一樣的速率下載一樣的資源,容許流媒體會話適應不一樣的數據速率。在開始一個流媒體會話時,客戶端會下載一個包含元數據的extended M3U (m3u8) playlist文件,用於尋找可用的媒體流。wiki

HLS協議是蘋果強推的一套協議,它有live和vod兩種模式(支持直播以及錄播視頻)。目前在移動端網頁支持較好,pc網頁上只有safrai和edge瀏覽器支持。

簡單介紹下HLS直播的工做模式,HLS 協議將視頻流(包含圖像以及聲音)編碼打包到 MPEG-2 TS容器中去,而後將把編碼好的 TS 文件等長切分紅後綴爲 ts 的小文件,並生成一個.m3u8的純文本索引文件;客戶端播放器HLS直播就是請求.m3u8索引文件,獲取到ts列表依次播放,播放結束以後再請求下一個.m3u8索引文件。

上面講的能夠知道HLS的延遲會很高,直播通常來講一個m3u8會包含3個切片,每一個切片至少是2s~3s,在加上網絡延遲,基本延遲會達到10s左右。

雖然延遲很高,可是移動端網頁基本都支持,因此HLS是手機H5直播的最佳選擇。

pc上除了safrai瀏覽器和efge瀏覽器能夠直接播放,其餘瀏覽器能夠經過mediaelementhls.jsvideojs-contrib-hls(這幾種是經過ajax請求hls流而後來播放的,因此會有跨域,http/https不能混合使用等問題,若是使用基於flash的播放器則沒有這些問題)等來播放。

HLS 直播示例代碼
使用hls.js播放,手機上直接用video播放便可

<video id="hls_player" width="600" height="400" controls></video>
<script src="//cdn.bootcss.com/hls.js/8.0.0-beta.3/hls.min.js"></script>
<script>
  const hlsVideo = document.getElementById('hls_player');
  if (Hls.isSupported()) {
    const hls = new Hls();
    hls.loadSource('xxx.m3u8');
    hls.attachMedia(hlsVideo);
    hls.on(Hls.Events.MANIFEST_PARSED, () => {
      hlsVideo.play();
    });
  }
</script>
複製代碼

總結

目前網頁直播pc上主要採用的協議爲RTMP與HDL(HTTP-FLV),手機上主要是HLS協議。

此外還有基於webrtc、ws+canvas的直播方案,不過目前應用都不是很普遍,本文就先不講了。

參考資料

  1. RTMP WIKI
  2. HTTP-FLV WIKI
  3. flv.js 參考
  4. HLS 協議詳解及 HLS 速度優化
  5. H5直播起航
相關文章
相關標籤/搜索