概述
HTTP Live Streaming(HLS)是一种由Apple开发的协议,用于通过HTTP分发流媒体数据。它将视频和音频数据分割成一系列的小文件片段,这些片段可以按需下载并顺序播放,从而提供低延迟和适应不同网络条件的能力。然而,并非所有的浏览器都原生支持HLS,这正是HLS.js发挥作用的地方。

什么是HLS.js?

HLS.js是一个轻量级的JavaScript库,旨在为不支持原生HLS的浏览器提供兼容性。它通过解析MPEG-TS流并在客户端进行解码,使HTML5 <video> 元素能够播放HLS内容。HLS.js利用了现代浏览器中的Media Source Extensions (MSE) 和 Encrypted Media Extensions (EME) API来实现这一目标。

特性与优势
  • 跨平台兼容性:HLS.js可以在几乎所有现代浏览器上运行,包括那些没有原生HLS支持的浏览器。
  • 自适应流传输:根据用户的网络状况动态调整视频质量,以优化播放体验。
  • DRM支持:通过集成EME API,HLS.js支持多种数字版权管理方案,如Widevine、PlayReady等。
  • 社区驱动:作为一个开源项目,HLS.js受益于广泛的社区贡献,持续改进和功能增强。

以上是简单介绍,下面提供使用一个 hls.js demo实例。将受支持播放的 .m3u8 链接赋值播放即可。 当然你也可以下载一个 VLC 来测试链接视频是否可以播放。

直接复制代码,验证一下提供方的视频地址是否有误
此处踩过坑 265格式web端不能播放,资源格式264可以正常播放
H265
在这里插入图片描述
H264
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>HLS.js 播放监控视频</title>
  <!-- 引入 hls.js -->
  <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 0;
      padding: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      background-color: #f4f4f4;
    }
    video {
      max-width: 100%;
      max-height: 100%;
      border: 1px solid #ccc;
      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
    }
  </style>
</head>
<body>
  <div>
    <h1 style="text-align: center;">HLS.js 播放监控视频</h1>
    <!-- 视频播放器 -->
    <video id="video" controls autoplay width="640" height="360"></video>
  </div>

  <script>
    // 获取 video 元素
    const video = document.getElementById('video');

    // HLS 流地址
    // const videoSrc = 'https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8';//测试开源地址
    const videoSrc = 'https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8';//测试回放地址

    // 检查是否支持 HLS.js
    if (Hls.isSupported()) {
      // 创建 HLS 实例
      const hls = new Hls();

      // 加载 .m3u8 文件
      hls.loadSource(videoSrc);

      // 将 HLS 实例绑定到 video 元素
      hls.attachMedia(video);

      // 监听事件:当 HLS 清单文件解析完成后自动播放
      hls.on(Hls.Events.MANIFEST_PARSED, () => {
        console.log('HLS stream loaded successfully');
        video.play();
      });

      // 监听错误事件
      hls.on(Hls.Events.ERROR, (event, data) => {
        console.error('HLS error:', data);
      });
    } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
      // 如果浏览器原生支持 HLS(如 Safari)
      video.src = videoSrc;
      video.addEventListener('loadedmetadata', () => {
        console.log('Native HLS playback supported');
        video.play();
      });
    } else {
      console.error('Your browser does not support HLS playback.');
    }
  </script>
</body>
</html>

下面是自己总结的一套初始化方法。
首先肯定要下载依赖的哈,如果是 cdn 方式的话 请参考上方简单 demo 实例。

npm run hls

页面demo:

<video id='myVideo' ref='localVideoPlayRef' class='video-js vjs-big-play-centered' playsinline
       crossorigin='anonymous' autoplay controls controlslist='nodownload'>
</video>

初始化函数:

// 初始化播放器
const initPlayer = () => {
  // video标签 demo元素
  const videoDemo = document.getElementById('myVideo')
  player.value = new Hls()
  player.value.attachMedia(videoDemo)
  const videoUrl: string = 'https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8' // 此处是播放的 .m3u8 链接
  // MEDIA_ATTACHED: 准备就绪时触发时间
  player.value.on(Hls.Events.MEDIA_ATTACHED, () => {
    player.value.loadSource(videoUrl)
  })

  // 如果是直播流( 这里是通过 判断是直播流  还是 点播流)
  if (!props.localVideo) {
    // 缓冲策略
    player.value.config.maxBufferLength = 60 // 设置最大缓冲时间为60秒
    player.value.config.minBufferLength = 3 // 设置最小缓冲时间为3秒

    // 动态比特率切换
    player.value.on(Hls.Events.LEVEL_SWITCHED, (event: any, data: any) => {
      console.log('比特率切换到级别:', data.level)
      player.value.startLoad()
    })
  }

  // 监听事件:当 HLS 清单文件解析完成后自动播放
  player.value.on(Hls.Events.MANIFEST_PARSED, () => {
    console.log('HLS 流加载成功')
    player.value.play()
  })
  // 监听缓冲事件,了解缓冲状态
  player.value.on(Hls.Events.BUFFER_FLUSHING, (event: any, data: any) => {
    console.log('‘缓冲区刷新事件触发:', data)
    if (data.live) {
      // 处理直播缓冲
      console.log('实时缓冲事件触发:', data)
    } else {
      // 处理VOD缓冲
      console.log('视频点播缓冲事件触发:', data)
    }
  })

  player.value.on(Hls.Events.ERROR, (event: any, data: any) => {
    if (data.fatal) {
      switch (data.type) {
        case Hls.ErrorTypes.NETWORK_ERROR:
          console.log('网络错误,尝试重新加载 HLS 源')
          // 尝试重新加载 HLS 源
          player.value.startLoad()
          break
        case Hls.ErrorTypes.MEDIA_ERROR:
          console.log('媒体错误,尝试切换播放速度')
          // 尝试切换播放速度
          player.value.recoverMediaError()
          break
        default:
          console.log('未知错误')
          // 其他错误,重置 HLS 实例
          player.value.destroy()
          player.value = new Hls()
          player.value.loadSource(videoUrl)
          player.value.attachMedia(videoDemo)
          break
      }
    }
  })
}

// 安全销毁播放器
const destroyPlayer = () => {
  if (player.value) {
    player.value.destroy()
    player.value = null
  }
}

// 创建 video demo 实例
const createVideo = () => {
  const videoElement = document.createElement('video')
  videoElement.id = 'myVideo'
  videoElement.className = 'video-js vjs-big-play-centered'
  videoElement.setAttribute('playsinline', '')
  videoElement.setAttribute('webkit-playsinline', '') // iOS 兼容
  videoElement.setAttribute('crossorigin', 'anonymous')
  videoElement.autoplay = true
  videoElement.controls = true
  videoElement.setAttribute('controlsList', 'nodownload')
  videoElement.setAttribute('ref', 'localVideoPlayRef')
  videoContainer.value!.appendChild(videoElement)
}

如果涉及多个视频可以切换的话 需要销毁对象实例:

await destroyPlayer()
await createVideo()
await nextTick(() => {
  initPlayer()
})

以上就是使用全流程。只是简单介绍下 平常用到的小功能知识点。对你有帮助的话,感谢点赞评论收藏。

更多推荐