安防监控ezhf 2019-11-05
默认vue已经安装好了,UI组件这里以vux为例,用什么UI库问题不大
注:循环这种实时视频的做法其实不推荐,但是你保不准,真的有这样的需要
npm i hls.js -S
<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>
// 结构略 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(); } }