默认vue已经安装好了,UI组件这里以vux为例,用什么UI库问题不大
注:循环这种实时视频的做法其实不推荐,但是你保不准,真的有这样的需要
1. 安装依赖 hls.js
npm i hls.js -S
2. 使用
2.1 html 循环渲染video节点
<div v-for="video in videos" :key="video.ref" class="videoList">
<p>
<span>XX监控</span>
<span>通道{{video.which}}</span>
<span><x-button @click.native="playVideo(video.which)" mini>播放</x-button><span>
</p>
<div class="videoContainer">
<video :ref='video.ref'></video>
</div>
</div>
2.2 【js】hls挂载节点,解析
// 结构略
import Hls from 'hls.js';
data() {
return {
videos: []
}
},
methods: {
// 节点挂载---$refs
attach() {
for (let index = 0; index < this.videos.length; index++) {
if (Hls.isSupported()) {
this.videos[index].hls = new Hls();
this.videos[index].hls.attachMedia(this.$refs[this.videos[index].ref][0]);
}
}
},
// 播放实时监控
playVideo(channel) {
let _this = this;
let videoRef = this.videos[channel-2].ref;
this.$refs[videoRef][0].controls = 'controls';
// 请求和心跳等涉及业务的略
_this.videos[channel-2].hls.loadSource(res.data.url);
// 正常解析
_this.videos[channel-2].hls.on(Hls.Events.MANIFEST_PARSED, function () {
_this.$refs[videoRef][0].play()
});
// 失败
_this.videos[channel-2].hls.on(Hls.Events.ERROR, function (event, data) {
if (data.fatal) {
switch(data.type) {
// 网络错误导致的错误,据观察这种类型的错,占比最高
case Hls.ErrorTypes.NETWORK_ERROR:
// 根据自己业务(心跳/错误次数 需要加载还是重新请求,这里只给出简单的,加载情况作为示例)
hls.startLoad();
break;
case Hls.ErrorTypes.MEDIA_ERROR:
// 多媒体错误
hls.recoverMediaError();
break;
default:
_this.videos[channel-2].hls.destroy();
_this.$nextTick(() => {
// 非网络或多媒体错误,重新获取url
_this.playVideo(channel);
})
break;
}
}
}
}
}
// 选择生命周期(需要$el已经存在,mounted()或者keep-alive的activated())
// 我这里使用的是activated()
activated(){
// axios 请求略(这里演示用固定数量,通道从2开始)
this.videos = [];
for (let i = 0; i < 5; i++) {
let item = {
hls: null,
ref: `video${i+2}`,
which: i+2,
}
this.videos.push(item)
this.$nextTick(() => {
// 可以放到请求地址成功后面(推荐)
this.attach()
})
}
}
// 销毁
deactivated() {
for (let i = 0; i < this.videos.length; i++) {
this.videos[i].hls.destroy();
}
}