web端播放m3u8視頻流注意事項

項目上有一個播放實時視頻(直播)的需求,後端童鞋直接傳過來一個相似 https://...️️/live.m3u8的視頻流地址。讓我自行播放,拿到地址的我一臉懵逼,下面開始個人探索(baidu)之路。git

HLS(HTTP Live Streaming)

介紹.m3u8以前得先介紹一下HLS技術,HLS是蘋果公司提出的,官方給出的簡介以下:github

使用Apple的HTTP實時流媒體(HLS)技術,將實時和點播的音頻和視頻發送到iPhone,iPad,Mac,Apple TV和PC。 使用與Web相同的協議,HLS容許您使用普通Web服務器和內容交付網絡部署內容。 HLS旨在提升可靠性,並經過針對可用的有線和無線鏈接速度優化回放來動態適應網絡條件。npm

HLS將音頻和視頻做爲一系列小文件發送,一般持續時間約爲6秒,稱爲媒體段文件。 索引文件或播放列表提供媒體段文件的URL的有序列表。 HLS的索引文件保存爲M3U8播放列表,這是用於MP3播放列表的M3U格式的擴展名。 客戶端訪問索引文件的URL,而後客戶端按順序請求索引文件。後端

簡而言之,.m3u8格式的文件是HLS技術下的產物,它是HLS的索引文件。若是看到後端童鞋傳給咱們的視頻流連接後綴是.m3u8,基本就能夠判定直播流採用的是HLS技術。瀏覽器

m3u8文件

出於好奇,我下載了其中一個.m3u8文件,並用電腦自帶的文本編輯器打開,內容以下:bash

它實際上就是一個普通的文本文件。服務器

  • #EXT-X-MEDIA-SEQUENCE:每個媒體文件在 PlayList中的惟一序列號,相鄰之間序號加一。上圖中是序號 303。
  • #EXT-X-TARGETDURATION:每一份媒體文件的時間, 以秒爲單位。 上圖中是2s。
  • #EXTINF:格式 #EXTINF <duration>,<title>duration:每一份 媒體文件持續時間;title:每個媒體文件url地址。上圖中seghik303.ts就是後綴爲.ts視頻切片文件的地址,這裏看上去應該是相對路徑。

如何在網頁上播放?

我項目裏是用的hls.js來播放的(以React爲例)。網絡

  1. 先安裝依賴
npm i hls.js
複製代碼
  1. 而後相應的文件頭裏引入
import Hls from 'hls.js';
複製代碼
  1. 頁面上放入標籤
<video id="hlsVedio"></video>
複製代碼
  1. 操做播放
componentDidMount() {
    const video = document.getElementById('hlsVedio');
    if (Hls.isSupported()) {
      const hls = new Hls();
      this.hls = hls;
      hls.loadSource('https://.../live.m3u8');
      hls.attachMedia(video);
      hls.on(Hls.Events.MANIFEST_PARSED, function() {
        video.play();
      });
    } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
      video.src = 'https://.../live.m3u8';
      video.addEventListener('loadedmetadata', function() {
        video.play();
      });
    }
  }
複製代碼

完成上面四步,基本上直播視頻流能夠播放了app

打開瀏覽器的控制檯看一下編輯器

它怎麼忽然穿了品如的衣服,它怎麼一直在發送請求?難道我代碼裏寫死循環了?仍是瀏覽器須要重啓一下?

再回過頭看一下HLS,發現這項流媒體技術就是會根據.m3u8的索引文件去不斷請求新的.m3u8.ts視頻文件。因此瀏覽器不斷髮送請求是正常的,不發送纔是不正常的。

  1. 銷燬視頻流

    componentWillUnmount() {
        if (this.hls) {
          this.hls.destroy();
        }
      }
    複製代碼

    千萬不要忘記在組件銷燬的生命週期裏銷燬建立的hls對象,否則在SPA應用裏切換頁面或者切換tab的時候,雖然看不到視頻組件了,但還會一直在發送請求。

相關文章
相關標籤/搜索