使用flvjs播放摄像头画面

更新时间: 2025-05-30 08:11:24

最近做公司内部使用的系统,需要接公司楼下的摄像头,后端给我的视频流地址是 .flv 的,所以我使用flv.js播放直播视频流。

flv.js是由bilibili网站开源的HTML5 Flash视频播放器,它允许在网页上直接播放FLV文件,而无需使用Flash插件。

这个库基于HTML5的Media Source Extentions技术,实现了将FLV文件流转码复用成ISO BMFF(MP4碎片),并通过MSE API喂给HTML5 video元素进行播放。

# 安装flv.js

npm install flv.js   
1

以下是flv.js的api文档,朋友们,要用一样工具就好好看文档,这是api caller要做的事情!
https://bilibili.github.io/flv.js/ (opens new window)

# Vue组件中使用

<template>
  <div class="video-container">
    <!-- 视频流会在这个video中播放,一定要的有这个video -->
    <video ref="videoRef" class="video-player" controls></video>
    <div class="controls">
      <button @click="play">播放</button>
      <button @click="pause">暂停</button>
      <button @click="stop">停止</button>
    </div>
  </div>
</template>

<script>
import flvjs from 'flv.js';

export default {
  data() {
    return {
      flvPlayer: null,
      videoUrl: 'http://xxxx.xx/xxx.flv' // 直播流地址
    };
  },
  mounted() {
    this.initPlayer();
  },
  beforeUnmount() {
    this.destroyPlayer();
  },
  methods: {
    initPlayer() {
      if (flvjs.isSupported()) { // 检测是否支持使用flvjs  
        // 创建播放器实例
        this.flvPlayer = flvjs.createPlayer({
          // 指示媒体类型,'flv'或'mp4'
          type: 'flv', 
          // 直播流地址
          url: this.videoUrl,
          // 指示数据是否为实时流
          isLive: true,
          // 指示流是否有音轨  
          hasAudio: true,
          // 指示流是否有视频轨道
          hasVideo: true,
          // 是否启用IO stashbuffer缓冲,如果是实时流播放需要设置为false  
          enableStashBuffer: false,
          // 对SourceBuffer执行自动清理,防止内存溢出  
          autoCleanupSourceBuffer: true
        });
        // 用于将flv.js播放器与video元素关联起来  
        this.flvPlayer.attachMediaElement(this.$refs.videoRef);
        // 加载视频  
        this.flvPlayer.load(); 
        // 开始播放  
        this.flvPlayer.play();

        // 错误处理
        this.flvPlayer.on(flvjs.Events.ERROR, (errorType, errorDetail) => {
          console.error('播放器错误:', errorType, errorDetail);
          this.handleError(errorType, errorDetail);
        });

        // 统计信息
        this.flvPlayer.on(flvjs.Events.STATISTICS_INFO, (stats) => {
          console.log('播放统计:', stats);
        });
      } else {
        console.error('浏览器不支持flv.js');
      }
    },
    play() {
      if (this.flvPlayer) {
        this.flvPlayer.play();
      }
    },
    pause() {
      if (this.flvPlayer) {
        this.flvPlayer.pause();
      }
    },
    stop() {
      this.destroyPlayer();
    },
    destroyPlayer() {
      if (this.flvPlayer) {
        this.flvPlayer.pause();
        this.flvPlayer.unload();
        this.flvPlayer.detachMediaElement();
        this.flvPlayer.destroy();
        this.flvPlayer = null;
      }
    },
    handleError(errorType, errorDetail) {
      switch (errorType) {
        case flvjs.ErrorTypes.NETWORK_ERROR:
          console.error('网络错误');
          this.recoverFromError();
          break;
        case flvjs.ErrorTypes.MEDIA_ERROR:
          console.error('媒体错误');
          break;
        default:
          console.error('未知错误');
      }
    },
    recoverFromError() {
      setTimeout(() => {
        this.destroyPlayer();
        this.initPlayer();
      }, 3000);
    }
  }
};
</script>
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113