每一个你不满意的现在,都有一个你不努力的曾经. 网站首页 > js
flv.js for Vue 多画面多流直播,动态生成dom并具有断线重连功能
发布时间:2023-07-07 15:37:11 修改时间:2023-07-07 15:37:11 阅读:1355 评论:0 0
弹框内容根据数组加载多视频流(http-flv)直播,动态生成dom并具有断线重连功能,关闭弹窗销毁全部流文件以及断线重连,即使释放内存,以防冗余逻辑导致内存溢出
安装:
npm install --save flv.js
引入(main.js);
import flvjs from 'flv.js'; Vue.prototype.$flvjs = flvjs;
Html:
<template> <div style="width: 100%;height:100%;position: relative;"> <!--触发dom--> <img @click="openLive()" src="../../assets/images/live.png" alt="" style="width: 60px;position: absolute;top: 18px;cursor:pointer"> <!--vue抽屉--> <el-drawer title="直播列表" :visible.sync="drawer" @close="drawClosed" size="60%" > <div class="videoList"> <div v-for="(n,index) in getAllAcraftData" style="width:calc(50% - 20px);float:left;height: 200px;margin: 5px;margin-bottom: 50px;"> <p style="width: 100%;height: 30px;line-height: 30px; background: #000;color: #fff;text-indent: 15px;"> {{n.aircraft?n.aircraft.name :'空名称'}}</p> <video :id="'refVideoJsItem'+ index" :ref="'refVideoJsItem'+ index" class="video-js vjs-default-skin vjs-big-play-centered" controls muted style="width:100%;height: 100%;" preload="auto"> </video> </div> </div> </el-drawer> </div> </template>
Css:
.videoList{ padding:0 20px; height: 76vh; overflow-y: scroll; }
Data:
data() { return { drawer: false, requireFlv:[], getAllAcraftData:[], timerCount:null, player:null, _player :[], } }
Method:
Created(){ this.getData(); }, methods: { // 请求页面数据 这里根据自己项目情况写 getData(){ this.$api.getData().then( res =>{ this.getAllAcraftData = res.data || []; // 事件循环 if(this.timerCount ){ clearTimeout(this.timerCount ); } this.timerCount = setTimeout(this.getData,3000) }) }, // flv 直播方法调用 openLive(){ const _this = this; _this.drawer = true; _this._player = []; async function videoHLSURL() { // 暂停重新赋值 _this.getAllAcraftData.forEach((data,index) =>{ const dom = 'refVideoJsItem' + index; if (_this.$flvjs.isSupported()) { var videoElement = document.getElementById(dom); var pl = ''; f(); function f() { pl = creatFlv(videoElement,data.liveUrl); if (data.liveUrl !== "" && data.liveUrl !== null) { pl.attachMediaElement(videoElement); pl.load(); pl.play(); } pl.on( _this.$flvjs.Events.ERROR, (errType, errDetail) => { console.log("重新连接中..."); //视频出错后销毁重新创建 if (pl) { // 销毁 if(_this.requireFlv[index]) { clearTimeout(_this.requireFlv[index]) } // 重建 _this.requireFlv[index] = setTimeout(()=>{ _this.destoryVideo(pl) f(); },3000 ); } }); } _this._player.push(pl) // 初始化flv function creatFlv(videoElement,url) { return _this.$flvjs.createPlayer({ type: "flv", isLive: true, fluid: true, stashInitialSize: 128,// 减少首桢显示等待时长 url: url },{ enableWorker: false, //不启用分离线程 enableStashBuffer: false, //关闭IO隐藏缓冲区 reuseRedirectedURL: true, //重用301/302重定向url,用于随后的请求,如查找、重新连接等。 autoCleanupSourceBuffer: true //自动清除缓存 }); } } }) }; setTimeout( videoHLSURL ,300); }, // 视频源定向销毁 destoryVideo(pl) { pl.pause(); pl.unload(); pl.detachMediaElement(); pl.destroy(); pl = null; }, // 视频源全局销毁 destoryVideoAll(){ if (this._player) { this._player.forEach((data,i) =>{ this.destoryVideo(this._player[i]) }) } }, // 断线重连销毁-关闭弹窗调用 drawClosed(){ this.clearFlv(); }, //断线重连销毁方法 clearFlv(){ if(this.requireFlv.length > 0 ) { this.requireFlv.forEach( (data,index)=>{ if(this.requireFlv[index]) { clearTimeout(this.requireFlv[index]) } }) this.requireFlv = [] } }, beforeDestroy(){ if(this.timerCount) { clearTimeout(this.timerCount); //关闭 } if (this._player) { this.destoryVideoAll() } // 销毁 this.clearFlv(); }, }
回复列表
关键字词:nbsp,span,style,font-size,1px,gt