FLV 流媒体格式是随着 Flash MX 的推出发展而来的视频格式。而 flv.js 是由 bilibili 团队编写维护的一个 JavaScript 播放插件库。

flv.js 的工作原理是将 FLV 文件流转换为 ISO BMFF(碎片化MP4)片段,然后通过媒体源扩展 API 将 mp4 片段馈送到 HTML5 元素 <video> 中。

特点

  • FLV 容器与 H.264 + AAC / MP3 编解码器播放
  • 分段分段视频播放
  • HTTP FLV 低延迟实时流播放
  • 通过网络套接字实时流播放的 FLV
  • 兼容 Chrome,FireFox,Safari 10,IE11 和 Edge。
  • 极低的开销,以及由浏览器加速的硬件!

安装

CMD

1
npm install --save flv.js

使用

项目是用 vue 框架启动的。

第一步先导入 flv.js

PLAINTEXT

1
2
3
4
<script>
// 导入 Flv
import flvjs from "flv.js";
</script>

第二步创建一个实例以及视频流地址:

PLAINTEXT

1
2
3
4
5
6
7
8
9
10
11
12
<script>
export default {
  data() {
    return {
      // flv实例
      flvPlayer: null,
      // 视频流地址
      flvUrl: 'http://www.xxx.com/video/test.flv'
    }
  }
}
</script>

第三步创建 flvjs 初始化

PLAINTEXT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<template>
	<div>
    <!-- 视频容器 -->
    <video autoplay muted height="100%" width="100%"  ref="videoItemRef"></video>
  </div>
</template>

<script>
export default {
  methods: {
    // 视频初始化
    createVideo() {
      // 判断是否能在浏览器播放
      if(flvjs.isSupported()) {
        let videoElement = this.$refs.videoItemRef;
        let url = this.flvUrl;
        
        // 创建flvjs
        this.flvPlayer = flvjs.createPlayer(
        	{
            type: "flv",
            hasAudio: false, //是否带音频播放
            cors: true,
            isLive: true,
            withCredentials: true,
            url: url, //你的url地址
            config: {
              autoCleanupSourceBuffer: true,
            },
          },
          {
            enableWorker: false, //不启用分离线程
            enableStashBuffer: true, //关闭IO隐藏缓冲区
            reuseRedirectedURL: true, //重用301/302重定向url,用于随后的请求,如查找、重新连接等。
            autoCleanupSourceBuffer: true, //自动清除缓存
            stashInitialSize: 128, // 减少首帧显示等待时长
            fixAudioTimestampGap: false,
          }
        );
        // 插入视频容器进行播放
        this.flvPlayer.attachMediaElement(videoElement);
      }
    }
  }
}
</script>

上面三步就是简单的创建 flvjs 播放视频的方法。

下面进行优化配置以及调整。

优化

追帧

由于流传输过来会导致有延迟问题,时间长了,延迟问题出现很严重,会导致视频慢上几秒甚至十几秒情况,所以我们需要追帧操作。

JS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
videoElement.addEventListener("progress", () => {
  if (this.flvPlayer.buffered != null) {
    let end = this.flvPlayer.buffered.end(0) || 0; //获取当前buffered缓冲区末尾值
    let delta = end - this.flvPlayer.currentTime; //获取buffered与当前播放位置的差值
    // 延迟过大,通过跳帧的方式更新视频
    if (delta > 10 || delta < 0) {
      this.flvPlayer.currentTime = this.flvPlayer.buffered.end(0) - 1;
      return;
    }
    // 追帧
    if (delta > 1) {
      videoElement.playbackRate = 1.2;
    } else {
      videoElement.playbackRate = 1;
    }
  }
})

重连

延时的问题可以通过跳帧的方法解决,但是如果视频卡顿导致流断了,那就可以重连。

注意:reloadVideo 方法我会在下面写出,这里是引用。

JS

1
2
3
4
5
this.flvPlayer.on(flvjs.Events.ERROR, (errType, errDetail) => {
  if (this.flvPlayer) {
    this.reloadVideo(this.flvPlayer); 
  }
})

处理视频卡住

视频有时候会出现第一次播放会播不出来,原因可能是网络不好导致,所以可以设置获取到视频流才开始播放视频。

JS

1
2
3
4
5
this.flvPlayer.on("statistics_info", (res) => {
  if (res.decodedFrames == 0 && this.flvPlayer.currentTime == 0) {
    this.flvPlayer.currentTime = 0;
  }
})

加载成功处理

加载成功视频就可以进行播放了。

JS

1
2
3
4
5
6
7
8
9
10
11
this.flvPlayer.on(flvjs.Events.METADATA_ARRIVED, () => {
  console.log("视频加载完成");
  let playPromise = videoElement.play();
  if (playPromise !== undefined) {
    playPromise
      .then(() => {
      	videoElement.play()
    	})
    	.catch(() => {})
  }
})

加载失败处理

加载失败就需要停止视频,不然会报错。

JS

1
2
3
4
this.flvPlayer.on("error", (err) => {
  this.flvPlayer.pause();
  console.log("err", err);
})

重新加载视频

上面优化提到 重连 加载视频,现在是 重连加载视频的事件。

一、先销毁视频 destoryVideo 事件下面会说明

二、重新加载视频

JS

1
2
3
4
5
6
7
// 重新加载视频
//  flvPlayer 参数为需要操作的实例
reloadVideo(flvPlayer){
  // 操作为 销毁视频
  this.destoryVideo(flvPlayer); 
  this.createVideo();
}

销毁实例

实例被销毁。

思路:判断实例是否存在,存在进行下一步。

JS

1
2
3
4
5
6
7
8
9
10
//  flvPlayer 要销毁的实例
destoryVideo(flvPlayer){
  if (flvPlayer) {
    flvPlayer.pause();
    flvPlayer.unload();
    flvPlayer.detachMediaElement();
    flvPlayer.destroy();
    flvPlayer = null;
  }
}
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐