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
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
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
原文链接:https://blog.csdn.net/weixin_51890314/article/details/114262827
上次更新: 10/21/2021, 1:52:09 PM