Carmineprince's Blog
首页
    • HTML
    • CSS
    • JavaScript
    • Vue
    • React
    • TypeScript
    • Node
    • Flutter
    • Electron
    • Python
    • 运维
    • 重学前端
  • 分类
  • 标签
  • 归档

Ziqi Wang

胡思乱想程序员
首页
    • HTML
    • CSS
    • JavaScript
    • Vue
    • React
    • TypeScript
    • Node
    • Flutter
    • Electron
    • Python
    • 运维
    • 重学前端
  • 分类
  • 标签
  • 归档
  • 从0开始搭建一套规范的Vue3.x项目工程环境
  • 解决vite构建vue3项目报错
  • 解决Vue3中无法使用$ref的问题
  • 项目中手动增加scss支持
  • el-table多选分页保留
  • 解决npm run dev启动两个页面问题
  • PC端和移动端兼容方案
  • SFC-Use-script-setup
  • vue2x面试前回炉重造
  • Vue3+Vite2配置
  • flvjs+vue 视频播放(手动追帧、断开重连、多个视频同时直播)
  • vue平滑滚动到指定位置
  • vant项目使用postcss-pxtorem和amfe-flexible 进行移动端适配
  • vue 使用v-html绑定时,内部元素不会继承外部css的解决方案
  • vue-awesome-swiper缩略图控制循环无效解决方案
  • 如何在Vue项目中优雅的使用svg图标
  • yarn报错及解决方案
  • vue3+ts+vite移动端vw适配方案
  • Vue项目中增加mockjs模拟接口请求
  • Nuxt相关

  • Vue3思考及跟Vue2相比的新变化总结
  • Vue相关
carmineprince
2021-10-20

flvjs+vue 视频播放(手动追帧、断开重连、多个视频同时直播)

# flvjs+vue 视频播放(手动追帧、断开重连、多个视频同时直播)

<script>
import flvjs from 'flv.js/dist/flv.min.js'

export default {
  name:'viewVideo',
  data() {
    return {
      src:"",  //flv格式的地址
      timerId:null,
      loadStatus:true,
      id: 'videoElement'+Math.random(),
      statusMsg:'摄像机未开启,请联系'
    };
  },
 created(){
     if(this.timerId){
      clearInterval(this.timerId)
      this.timerId=null
    }
  },
   mounted() {
      this.$nextTick(() => {
        this.setsrc();
      })
    },
  destroyed(){
    console.log("destorying video");
    if(this.timerId){
      clearInterval(this.timerId)
      this.timerId=null
    }
    if (this.flvPlayer !== null) {
        this.flvPlayer.pause();
        this.flvPlayer.destroy();
        this.flvPlayer = null;
      }
  },
  methods: {
    createVideo(){
      let that=this
     console.log(that.flvPlayer);
       if (that.flvPlayer) {
           that.flvPlayer.pause();
           that.flvPlayer.destroy();
           that.flvPlayer = null;
        }
         if (that.timerId !== null) {
         clearInterval(that.timerId);
            }
      that.videoElement = document.getElementById(that.id)
      if (flvjs.isSupported()) {
        that.flvPlayer = flvjs.createPlayer({
          type: 'flv',
          url: that.src,
          isLive: true, 
        },{
             cors: true, // 是否跨域
            enableWorker: true, // 是否多线程工作
            enableStashBuffer: false, // 是否启用缓存
            stashInitialSize: 128, // 缓存大小(kb)  默认384kb
            autoCleanupSourceBuffer: true // 是否自动清理缓存
        })
      }
         that.flvPlayer.on(flvjs.Events.ERROR, (errorType, errorDetail, errorInfo) => {
		    console.log("errorType:", errorType);
        console.log("errorDetail:", errorDetail);
        console.log("errorInfo:", errorInfo);
        // this.loadStatus=true
        // this.statusMsg="正在重连。。。"
        //视频出错后销毁重新创建
         if (that.flvPlayer) {
          that.flvPlayer.pause();
          that.flvPlayer.unload();
          that.flvPlayer.detachMediaElement();
          that.flvPlayer.destroy();
          that.flvPlayer= null;
        }
          that.createVideo();
      });
      that.flvPlayer.on("statistics_info", function (res) {
       if (that.lastDecodedFrame == 0) {
         that.lastDecodedFrame = res.decodedFrames;
         return;
       }
       if (that.lastDecodedFrame != res.decodedFrames) {
         that.lastDecodedFrame = res.decodedFrames;
       } else {
           that.lastDecodedFrame = 0;
           if (that.flvPlayer) {
             that.flvPlayer.pause();
             that.flvPlayer.unload();
             that.flvPlayer.detachMediaElement();
             that.flvPlayer.destroy();
             that.flvPlayer= null;
              that.createVideo();
         }
           
       }
     });

             that.flvPlayer.attachMediaElement(this.videoElement)
             that.flvPlayer.load()
            that.flvPlayer.play()
            if (that.timerId !== null) {
          clearInterval(that.timerId);
             }
         that.timerId = setInterval(() => {
          if (that.videoElement.buffered.length > 0) {
            const end = that.videoElement.buffered.end(0);  // 视频结尾时间
            const current = that.videoElement.currentTime;  //  视频当前时间
            const diff = end - current;// 相差时间
            console.log(diff);
            const diffCritical = 4; // 这里设定了超过4秒以上就进行跳转
            const diffSpeedUp = 1; // 这里设置了超过1秒以上则进行视频加速播放
            const maxPlaybackRate = 4;// 自定义设置允许的最大播放速度
            let playbackRate = 1.0; // 播放速度
            if (diff > diffCritical) {
              console.log("相差超过4秒,进行跳转");
              that.videoElement.currentTime = end - 1.5;
              playbackRate = Math.max(1, Math.min(diffCritical, 16));
            } else if (diff > diffSpeedUp) {
              console.log("相差超过1秒,进行加速");
              playbackRate = Math.max(1, Math.min(diff, maxPlaybackRate, 16))
            }
            that.videoElement.playbackRate = playbackRate;
            if (that.videoElement.paused) {
              that.flvPlayer.play()
            }
          }
        }, 1000);
    },
    setsrc(){
    if(this.url){
    this.src =this.url;
    this.createVideo();
    }
  },
},
  props: {
    url:  {
        default: null,
        required: true,
        type: String | null
      },
  },
    watch: {
      url: {
        handler(newValue) {
        if(newValue != null){
          this.loadStatus=false
          this.src=newValue
          this.$nextTick(() => {
        this.setsrc();
      })
        }
        },
        deep: true,
        immediate: true,
      }
    },
}
</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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
<template>
  <div class="hello" style="width:100%; height:100%;background-color:#000000;">
    <section  v-if="!loadStatus" style="width:100%; height:100%;">
      <video autoplay controls width="100%" height="100%" :id="id"  muted></video>
    </section>
    <div v-else
         style="width: 100%;height: 100%;display: flex;justify-content:center;align-items:center;cursor: pointer">
      <span style="color: wheat;font-size: 14px;"><i class="el-icon-warning-outline" style="margin-right: 10px"></i>{{statusMsg}}</span>
    </div>
  </div>
</template>
1
2
3
4
5
6
7
8
9
10
11
<style scoped>
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

原文链接:https://blog.csdn.net/weixin_51890314/article/details/114262827

#flvjs#vue#视频
上次更新: 10/21/2021, 1:52:09 PM
Vue3+Vite2配置
vue平滑滚动到指定位置

← Vue3+Vite2配置 vue平滑滚动到指定位置→

最近更新
01
pc端rem配置
03-02
02
使用动态变量ts报错的解决
02-25
03
React Hook详解
02-18
更多文章>
Theme by Vdoing | Copyright © 2021-2022 Carmineprince | 鲁ICP备2021046263号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式