使用flv.js实现多路直播

背景

前一段时间大佬实现了大华摄像头的推流,但是在多路播放直播时,还有一点小问题,我改了一下大佬的多路播放直播,简单记录一下。
前端是Vue项目,用到了flv.js来播放直播流,不过现在flv.js好像没有维护了。

遇到的问题

在开发过程中,遇到了挺多的问题。比如在没有销毁直播流的情况下,又开启了该直播流,这会导致浏览器疯狂报错。如下图所示:
在这里插入图片描述
又或者是离开画面后,延时会累加,导致整个画面延时太高。

局部代码


 <div v-if="dataList.length > 0" :class="cellClass(i)" v-for="i in selectProportion" :key="i">
   <div class="player">
   	<video  :id="'videoElement' + (i-1)" v-if="dataList[i-1].isOn===1"  autoplay muted="muted" width="100%" height="100%">
   	</video>
    <div v-else class="videoText">
     {{ dataList[i-1].alias }}
      <div class="msgVideoText">该设备不存在</div>
	</div>
  </div>
</div>

import flvjs from "flv.js";

export default {
  data() {
    return {
      select: 0,
      //选中的播放数量
      selectProportion: 1,
      //直播流地址对象数组
      dataList: [],
      flvPlayer: null,
      lastDecodedFrame: 0,
      //video标签id
      elementId: "",
      //flvPlayer数组,方便销毁
      flvPlayerArr:[],
    }
  },
  methods: {
	  changeSelect(item, index) {
      this.select = index
      this.deviceId = item.deviceId
      this.changeMultiVideo()
    },
    playVideo(device,id) {
      let _this=this;
      var deviceId = device.deviceId
      _this.lastDecodedFrame = 0
      _this.elementId = deviceId
      let videoWin = ""
      videoWin = document.getElementById( 'videoElement'+id);
      if (flvjs.isSupported()) {
        let flvPlayer = flvjs.createPlayer({
          type: "flv",// 媒体类型
          isLive: true,//是否是实时流
          hasAudio: false,//是否有音频
          url: window.SITE_CONFIG.rtmp + deviceId,// 视频流地址
          stashInitialSize: 128 // 减少首帧显示等待时长
        }, {
          enableWorker: false,// 不启动分离线程
          enableStashBuffer: false,// 关闭IO隐藏缓冲区
          reuseRedirectedURL: true,// 重用301、302重定向url,用于随后的请求,入查找、重新连接等。
          autoCleanupSourceBuffer: true, // 自动清除缓存
          fixAudioTimestampGap: false,// false 音频同步
        });
        // 断流重连
        flvPlayer.on(flvjs.Events.ERROR, (errorType, errorDetail, errorInfo) => {
          console.log("errorType:", errorType);
          console.log("errorDetail:", errorDetail);
          console.log("errorInfo:", errorInfo);
          if (flvPlayer) {
            _this.destroyVideo();
          }
        });
        // 画面卡死重连
        flvPlayer.on("statistics_info", function (res) {
          if (_this.lastDecodedFrame == 0) {
            _this.lastDecodedFrame = res.decodedFrames;
            return;
          }
          if (_this.lastDecodedFrame != res.decodedFrames) {
            _this.lastDecodedFrame = res.decodedFrames;
          } else {
            _this.lastDecodedFrame = 0;
            if (flvPlayer) {
              _this.changeMultiVideo()
            }
          }
        });
        flvPlayer.attachMediaElement(videoWin);
        flvPlayer.load();
        //将启动的直播流添加到数组里,方便统一销毁
        _this.flvPlayerArr.push(flvPlayer)
      }
    },
    //销毁断流方法
    destroyVideo() {
      let _this=this;
      for(let i=0;i<_this.flvPlayerArr.length;i++){//卸载已经加载的视频资源
        if (_this.flvPlayerArr[i]!=null){
          console.log("销毁视频资源")
          _this.flvPlayerArr[i].pause();
          _this.flvPlayerArr[i].unload();
          _this.flvPlayerArr[i].detachMediaElement();
          _this.flvPlayerArr[i].destroy();
          _this.flvPlayerArr[i]=null;
        }
      }
    },

    //不同的播放策略
    changeMultiVideo(){
      this.destroyVideo()
      this.$nextTick(()=>{
        console.log(this.selectProportion)
        //单个监控则不需要额外的video和id
        if (this.selectProportion===1){
          if (this.dataList[this.select].isOn===1) {
            this.playVideo(this.dataList[this.select], "")
          }
        }else {
          for (let i = 0; i < this.selectProportion; i++) {
            if (this.dataList[i].isOn===1){
              this.playVideo(this.dataList[i],i)
            }
          }
        }
      });
    }
  },


  computed: {
    cellClass() {
      return function (index) {
        switch (this.selectProportion) {
          case 1:
            return ['cell-player-1']
          case 4:
            return ['cell-player-4']
          case 6:
              return ['cell-player-6']
          case 9:
            return ['cell-player-9']
          case 16:
            return ['cell-player-16']
          default:
            break;
        }
      }
    },
  },
  //切换页面关闭video
  deactivated() {
    this.destroyVideo()
  }
}

结束

做完这个之后,发现浏览器只能播放6路http-flv流,具体如何解决暂时还没想好,看网上说是因为浏览器限制同源HTTP/1.x连接并发个数。最后,我只是个半吊子后端,对vue也不是很熟悉,如有错误还请多多谅解。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值