Hls.js 使用文档

20,250 阅读6分钟

前言

文章是github的搬运及自己在使用过程中的记录。

hls.js是一个JavaScript库,可实现HTTP Live Streaming客户端。 它依靠HTML5视频和MediaSource扩展进行播放。

它通过将MPEG-2传输流和AAC / MP3流转换为ISO BMFF(MP4)片段来工作。 如果在浏览器中可用,可以使用Web Worker异步执行此转换。 WWDC2016期间宣布,hls.js还支持HLS + fmp4

hls.js不需要任何播放器,它可以直接在标准HTML 元素上运行。

hls.js用ECMAScript6(* .js)和TypeScript(* .ts)(ES6的强类型超集)编写,并使用TypeScript编译器在ECMAScript5中进行编译。

用TS和纯JS / ES6编写的模块可以相互依赖,也可以相互导入/要求。

为了构建发行包并为我们的开发环境提供服务,使用Webpack。

github地址:github.com/video-dev/h…

特征

  • VOD 和现场播放列表

  • 实时播放列表上的 DVR 支持

  • 碎片化的 MP4 容器

  • MPEG-2 TS 容器

  • ITU-T 建议书 H.264 和 ISO/IEC 14496-10 基本流

  • ISO/IEC 13818-7 ADTS AAC 基本流

  • ISO/IEC 11172-3 / ISO/IEC 13818-3(MPEG-1/2 Audio Layer III)基本流

  • 打包元数据 (ID3v2.3.0) 基本流

  • AAC 容器(仅音频流)

  • MPEG 音频容器(MPEG-1/2 Audio Layer III 仅音频流)

  • HTTP Live Streaming 的定时元数据(ID3 格式,MPEG-2 TS 承载)

  • AES-128 解密

  • SAMPLE-AES 解密(仅当使用 MPEG-2 TS 容器时才支持)

  • 对 DRM(数字权限管理)的加密媒体扩展 (EME) 支持

  • Widevine CDM(仅在演示页面上使用shaka-packager test-stream 进行测试)

  • CEA-608/708 字幕

  • WebVTT 字幕

  • 用于 VoD 和现场播放列表的备用音轨再现(带有备用音频的主播放列表)

  • 自适应流媒体

  • 手动和自动质量切换

    • 3种质量切换模式可用(可通过API方式控制)

      • 即时切换(在当前视频位置即时质量切换)
      • 平滑切换(下一个加载片段的质量切换)
      • 带宽保守切换(下一个加载片段的质量切换更改,不刷新缓冲区)
    • 在自动质量模式下,紧急关闭以防带宽突然下降以最小化缓冲。

  • VoD & Live 上的准确搜索(不限于片段或关键帧边界)

  • 无需重新下载段即可在缓冲区和后台缓冲区中查找的能力

  • 内置分析

  • 可以监控所有内部事件(网络事件、视频事件)

  • 播放会话指标也公开

  • 容错能力

  • 库中嵌入的重试机制

  • 可以触发恢复操作修复致命的媒体或网络错误

  • 冗余/故障转移播放列表

支持的 M3U8 标签

有关 HLS 格式和这些标签含义的详细信息,请参阅tools.ietf.org/html/draft-…rfc8216bis-08>

清单标签

  • #EXT-X-STREAM-INF:<attribute-list> <URI>
  • #EXT-X-MEDIA:<attribute-list>
  • #EXT-X-SESSION-DATA:<attribute-list>

以下属性已添加到其各自变体的属性列表中,但未在其选择和播放中实现。

  • VIDEO-RANGEHDCP-LEVEL(见#2489

播放列表标签

  • #EXTM3U
  • #EXT-X-VERSION=<n>
  • #EXTINF:<duration>,[<title>]
  • #EXT-X-ENDLIST
  • #EXT-X-MEDIA-SEQUENCE=<n>
  • #EXT-X-TARGETDURATION=<n>
  • #EXT-X-DISCONTINUITY
  • #EXT-X-DISCONTINUITY-SEQUENCE=<n>
  • #EXT-X-BYTERANGE=<n>[@<o>]
  • #EXT-X-MAP:<attribute-list>
  • #EXT-X-KEY:<attribute-list>METHOD=SAMPLE-AES仅支持 MPEG-2 TS 段)
  • #EXT-X-PROGRAM-DATE-TIME:<attribute-list>
  • #EXT-X-START:TIME-OFFSET=<n>
  • #EXT-X-SERVER-CONTROL:<attribute-list>
  • #EXT-X-PART-INF:PART-TARGET=<n>
  • #EXT-X-PART:<attribute-list>
  • #EXT-X-PRELOAD-HINT:<attribute-list>
  • #EXT-X-SKIP:<attribute-list>
  • #EXT-X-RENDITION-REPORT:<attribute-list>

以下标签被添加到各自片段的属性列表中,但未在流媒体和播放中实现。

  • #EXT-X-DATERANGE:<attribute-list>(未添加到元数据 TextTracks。见#2218
  • #EXT-X-BITRATE (未用于 ABR 控制器)
  • #EXT-X-GAP(未实现。见#2940

不支持

有关问题的完整列表,请参阅“发布计划和待办事项”项目选项卡中的“最高优先级”。编解码器支持取决于运行时环境(例如,并非同一操作系统上的所有浏览器都支持 >HEVC)。

  • CMAF CC 支持#2623
  • Emsg“元数据”TextTracks 中 FMP4(Emsgv1 中的 ID3)的带内定时元数据[#2360]>(github.com/video-dev/h…)
  • #EXT-X-DATERANGE在“元数据”TextTracks #2218
  • #EXT-X-GAP填充#2940
  • #EXT-X-I-FRAME-STREAM-INF I 帧媒体播放列表文件
  • SAMPLE-AES 带有 fmp4、aac、mp3、vtt... 片段(仅限 MPEG-2 TS)
  • PlayReady 和 FairPlay DRM(参见#3779标记为 DRM 的问题
  • 基于运行时媒体功能的高级变体选择(请参阅标记为 的问题[media-capabilities]>(github.com/video-dev/h…
  • Windows 10 上的 IE 和 Edge (<=18) 中的 MP3 基本流音频(请参阅#1641Microsoft 回答论坛

服务器端渲染 (SSR) 和require来自 Node.js 运行时

您可以安全地在 Node 中使用这个库,绝对不会发生任何事情。导出一个虚拟对象,以便要求库不会引发错误。>HLS.js 在 Node.js 中不可实例化。有关更多详细信息,请参阅#1841

依赖

1.node.js 
2.npm
3.git
4.webpack
5.webpack-cli

demo项目

首先拉取github中的项目代码,并安装所需依赖(示例项目需要vpn才能播放视频流)

git clone https://github.com/video-dev/hls.js.git
cd hls.js
# 代码拉取完成后确保依赖的安装及更新
npm install ci
#  在开发环境下运行demo页面(用file-watch重新编译项目,但不生成dist包),运行不成功的话尝试使用npm install解决报错
npm run dev
# 若有变更使用 sanity-check检查变更后再进行提交
npm run sanity-check

使用

第一步:设置和支持

首先在您的网页中包含https://cdn.jsdelivr.net/npm/hls.js@latest

<script src="//cdn.jsdelivr.net/npm/hls.js@latest"></script>

调用以下静态方法:Hls.isSupported()检查您的浏览器是否支持MediaSource Extensions

<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<script>
  if (Hls.isSupported()) {
    console.log('hello hls.js!');
  }
</script>

第二步:实例化Hls对象并绑定到<video>元素

让我们

  • 创建一个<video>元素
  • 创建一个新的 HLS 对象
  • 将视频元素绑定到此 HLS 对象
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script><video id="video"></video>
<script>
  if (Hls.isSupported()) {
    var video = document.getElementById('video');
    var hls = new Hls();
    // bind them together
    hls.attachMedia(video);
    // MEDIA_ATTACHED event is fired by hls object once MediaSource is ready
    hls.on(Hls.Events.MEDIA_ATTACHED, function () {
      console.log('video and hls.js are now bound together !');
    });
  }
</script>

第三步:加载清单

您需要提供如下清单 URL:

<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script><video id="video"></video>
<script>
  if (Hls.isSupported()) {
    var video = document.getElementById('video');
    var hls = new Hls();
    // bind them together
    hls.attachMedia(video);
    hls.on(Hls.Events.MEDIA_ATTACHED, function () {
      console.log('video and hls.js are now bound together !');
      hls.loadSource('http://my.streamURL.com/playlist.m3u8');
      hls.on(Hls.Events.MANIFEST_PARSED, function (event, data) {
        console.log(
          'manifest loaded, found ' + data.levels.length + ' quality level'
        );
      });
    });
  }
</script>

第四步:通过<video>元素控制

视频是通过 HTML<video>元素控制的。

HTMLVideoElement 控件和事件可以无缝使用。

video.play();

第五步:错误处理

所有错误都通过唯一的单个事件发出信号。

每个错误按以下方式分类:

  • 它的类型:

    • Hls.ErrorTypes.NETWORK_ERROR 对于网络相关的错误
    • Hls.ErrorTypes.MEDIA_ERROR 媒体/视频相关错误
    • Hls.ErrorTypes.OTHER_ERROR 对于所有其他错误
  • 它的详细信息:

  • 它的死亡率:

    • false 如果错误不是致命的,hls.js 将尝试恢复它
    • true 如果错误是致命的,则需要采取措施(尝试)恢复它。

完整的细节描述如下

请参阅下面的示例代码以侦听错误:

hls.on(Hls.Events.ERROR, function (event, data) {
  var errorType = data.type;
  var errorDetails = data.details;
  var errorFatal = data.fatal;
​
  switch (data.details) {
    case Hls.ErrorDetails.FRAG_LOAD_ERROR:
      // ....
      break;
    default:
      break;
  }
});

致命错误恢复

hls.js 提供了通过以下 2 种方法“尝试”恢复致命网络和媒体错误的方法:

hls.startLoad()

应调用以恢复网络错误。

hls.recoverMediaError()

应调用以恢复媒体错误。

错误恢复示例代码
hls.on(Hls.Events.ERROR, function (event, data) {
  if (data.fatal) {
    switch (data.type) {
      case Hls.ErrorTypes.NETWORK_ERROR:
        // try to recover network error
        console.log('fatal network error encountered, try to recover');
        hls.startLoad();
        break;
      case Hls.ErrorTypes.MEDIA_ERROR:
        console.log('fatal media error encountered, try to recover');
        hls.recoverMediaError();
        break;
      default:
        // cannot recover
        hls.destroy();
        break;
    }
  }
});
hls.swapAudioCodec()

如果调用后仍然引发媒体错误hls.recoverMediaError(),调用此方法可能有助于解决音频编解码器不匹配的问题。工作流程应该是:

关于第一媒体错误:调用 hls.recoverMediaError()

如果在第一个媒体错误之后“快速”引发另一个媒体错误:首先调用hls.swapAudioCodec(),然后调用hls.recoverMediaError()

最后一步:销毁,在流之间切换

hls.destroy() 应调用以释放使用的资源并销毁 hls 上下文。