m3u8是苹果公司推出的视频播放标准,是m3u的一种,只是编码格式采用的是UTF-8。m3u8准确来说是一种索引文件,使用m3u8文件实际上是通过它来解析对应的放在服务器上的视频网络地址,从而实现在线播放。


m3u8格式的视频是将文件分成一小段一小段的ts文件,播放完一个在播放下一个,由于每次请求的ts文件都很小,所以基本可以做到无延时播放。目前WEB上主流的直播方案主要是HLS和RTMP,移动端主要是HLS,PC端主要是RTMP。

HLS是苹果推出的,移动端不管是IOS还是Android都天然支持HLS协议,直接在h5页面直接配置即可使用;PC端只有safari浏览器支持,其他浏览器均不支持。

需要借助hls插件,可以用video.js和videojs-contrib-hls.js。video.js是非常好用的插件

type:application/x-mpegURL // 告诉videojs,这是一个hls流

HLS

Hls.js 使用文档 - 掘金

GitHub - video-dev/hls.js

1、使用npm安装hls.js或者外部引入;

npm install --save hls.js
<script src="https://cdn.jsdelivr.net/npm/hls.js@1.2.7/dist/hls.js"></script>

2、使用

<template>
  <div class="page">
    <video controls id="video" autoplay="autoplay">
         <source
            type="application/x-mpegURL">
    </video>
</div>
</template>
<script lang="ts">
// import HLS from 'hls.js';
import {defineComponent} from "vue";
var HLS = (window as any).Hls;
let hls = new HLS()
//声明两个变量
export default defineComponent({
  methods: {
    //点击播放
    start(){
      if (HLS.isSupported()) {
        var video = <HTMLVideoElement>document.getElementById('video');
        hls.attachMedia(video);
        hls.loadSource('1.m3u8');
        hls.on(HLS.Events.MANIFEST_PARSED, () => {
          video.play();
          console.log("加载成功");
        });
        hls.on(HLS.Events.ERROR, (event, data) => {
          console.log("加载失败");
        });
      }
    }
  },
  mounted(){
    this.start();
  }
})
</script>

3、接口

@RequestMapping("/video/{file}")
    public void video( HttpServletResponse response, @PathVariable("file") String file){
        try {
            file = dir + file;
            ServletOutputStream out = response.getOutputStream();
            byte b[] = readFileToByteArray(file); //一开始固定读取1024字节,导致前端解析一直错误,应该是文件多少字节就读取多少字节内容
            out.write(b);
            out.flush();
        } catch (Exception e){

        }
    }

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

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

ios获取m3u8地址 iphone怎么打开m3u8_ide

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

二、video.js + video.hls.js

官网:Home | Video.js Documentation

中文文档:video.js -HTML5 视频播放器

videojs中文文档详解


<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>前端播放m3u8格式视频</title>
    <!--https://www.bootcdn.cn/video.js/-->
    <link href="https://cdn.bootcss.com/video.js/7.6.5/alt/video-js-cdn.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/video.js/6.6.2/video.js"></script>
    <!--https://www.bootcdn.cn/videojs-contrib-hls/-->
    <script src="https://cdn.bootcss.com/videojs-contrib-hls/5.15.0/videojs-contrib-hls.min.js"></script>
</head>
<body>
    <video id="myVideo" class="video-js vjs-default-skin vjs-big-play-centered" controls preload="auto" width="1080" height="708" data-setup='{}'>    
        <source type="application/x-mpegURL"> //source 标签是设置静态资源的,如果是通过video的api动态设置文件,这标签不需要,不然会有一些问题
    </video>
</body>
<script>    
    // videojs 简单使用  
    var myVideo = videojs('myVideo',{
        bigPlayButton : true, 
        textTrackDisplay : false, 
        posterImage: false,
        errorDisplay : false,
    })
    myVideo.src([
          {
            src: "视频.m3u8",
            type: "application/x-mpegURL", // 告诉videojs,这是一个hls流
          },
        ]);
    myVideo.play() // 视频播放
    myVideo.pause() // 视频暂停
</script>
</html>

或者直接使用video.js,会自动扫video元素加载

<!DOCTYPE html>
<html lang="">
  <head>
    <link href="https://unpkg.com/video.js/dist/video-js.css" rel="stylesheet">
    <script src="https://unpkg.com/video.js/dist/video.js"></script>
  </head>
  <body>
    <video class="video-js vjs-default-skin vjs-big-play-centered" controls preload="auto" width="1080" height="708" data-setup='{}'> 
      <source src="video.m3u8" type="application/x-mpegURL">
    </video>
  </body>
</html>