hls.js的使用非常简单,以下为其官方的demo:

<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<video id="video"></video>
<script>
  var video = document.getElementById('video');
  var videoSrc = 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8';
  if (Hls.isSupported()) {
    var hls = new Hls();
    hls.loadSource(videoSrc);
    hls.attachMedia(video);
  }
</script>

该框架的配置多大几十项,一般情况下使用默认配置即能满足绝大部分场景。但是如果针对一些特殊场景需要更改配置,对一般开发者来说并非易事。所以,如果精准控制,还得搞懂每一项的具体是怎么执行的。

hls.js库是基于eventemitter3用于事件的监听和派发,这样处理逻辑松耦合,虽然当事件多起来后维护需要一定成本,但是基于hls.js在加载视频流到播放过程中,存在很多多个事件监听一个事件的场景,所以采用eventemitter也是十分合适的,而且也方便业务方增加监听事件。

hls.js库根据功能划分为多个controller,如abr-controllerbuffer-controllerstream-controller等,每个controller任务明确,通过事件监听派发的方式完成视频流的拉取、解析、播放等。

hls.js从初始化到加载m3u8,到选择不同码率加载对应ts文件,再解码ts转为mp4最终在浏览器播放,整个过程非常复杂,作者整理了一个流程图如下:

其中,几个关键环节对应的含义如下所示:

MANIFEST_LOADING: 开始加载playlist m3u8资源
MANIFEST_LOADED: playlist m3u8文件加载完成
MANIFEST_PARSED:playlist m3u8解析完成
LEVEL_LOADING: 加载特定码率的m3u8文件
LEVEL_LOADED: 特定码率的m3u8文件解析完成,拿到该码率对应的ts列表
FRAG_LOADING: 开始加载某个ts分片文件,开始根据ts片下载时间预估带宽
FRAG_LOADED: ts分片文件加载成功,开始转码
BUFFER_APPENDING: 视频流赋给video标签

主流程中有两个关键的定时器,第一个为StreamController启动用来轮询ts文件列表是否更新结束;第二个为在ts片加载过程中,用来轮询监听当前ts下载速率以动态调节不同的码率,hls.js初始默认码率为playlist的中间码率,如当前码率列表为360p480p720p,则初始默认取480p