flv.js for Vue 多画面多流直播,动态生成dom并具有断线重连功能

弹框内容根据数组加载多视频流(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();
     },
}
Vue中使用video.js动态渲染多个直播流视频是可行的。首先,您需要引入video.js和相应的插件。 1. 安装video.js: 您可以使用npm或yarn来安装video.js库,`npm install video.js`或`yarn add video.js`。 2. 在Vue组件中导入video.js: 在您的Vue组件中,您需要导入video.js和任何其他相关的插件。您可以使用以下语句进行导入: ```javascript import videojs from 'video.js'; import 'video.js/dist/video-js.css'; // 导入video.js的CSS样式文件 ``` 3. 创建Vue组件: 创建一个Vue组件,用于渲染video.js播放器。在组件中,您可以使用`v-for`指令来动态渲染多个视频。 ```html <template> <div> <!-- 使用v-for指令渲染多个video标签,每个video标签都有唯一的ID和video.js的class --> <video v-for="video in videos" :key="video.id" :id="video.id" class="video-js"></video> </div> </template> <script> export default { data() { return { videos: [ { id: 'video1', src: 'http://livestreamurl1' }, { id: 'video2', src: 'http://livestreamurl2' }, // 添加更多的视频 ] }; }, mounted() { // 在组件挂载后,使用video.js动态创建播放器 this.videos.forEach(video => { videojs(video.id, { sources: [{ src: video.src, type: 'application/x-mpegURL' }] }); }); } }; </script> ``` 上述代码中使用了v-for指令来循环渲染多个video标签,并为每个video标签添加了唯一的ID和video.js的class。在组件挂载后,使用video.js的API为每个video标签创建播放器,并传入相应的视频源。 这样就能够实现在Vue动态渲染多个直播流视频了。记得在组件销毁时销毁播放器,以及根据需要进行其他配置和功能的设置。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.T's Blog

感谢打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值