由于项目需要同时显示两个相机的视频,使用上一篇文章封装的组件无法完成,因为当时webVideoCtrl.js是直接定义在全局的,$相当于一整个项目的window,无论怎么使用都只能在第一次定义的dom位置显示视频(如果有更好的方法欢迎评论区告知),因此使用了iframe隔离window。

1.在public地址下添加iframe.html

在这里插入图片描述

2.iframe.html

<!doctype html>
<html>
<head>
    <title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="Pragma" content="no-cache" />
    <meta http-equiv="Cache-Control" content="no-cache, must-revalidate" />
    <meta http-equiv="Expires" content="0" />
</head>
<style type="text/css">
html, body {
    margin: 0;
    padding: 0;
    border: 0;
    width: 100%;
    height: 100%;
}
.plugin {
    width: 100%;
    height: 100%;
}
</style>
<body>
    <div id="divPlugin" class="plugin"></div>
</body>
<script type="text/javascript" src="static/haikang/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="static/haikang/webVideoCtrl.js"></script>
<script>
  // 向父vue页面发送信息
  window.parent.postMessage({
      cmd: 'run',
      params: {
        success: true
      }
  }, '*');
  // 接受父页面发来的信息
  window.addEventListener("message", function(event){
    var data = event.data;
    switch (data.cmd) {
      case 'getFormJson':
          // 处理业务逻辑
          companyVideoData = data.params
          videoInitPlugin()
          break;
      }
  });
  var companyVideoData = {}
  // 接受父页面发来的信息
  function videoInitPlugin() {
    var iRet = WebVideoCtrl.I_CheckPluginInstall();
    if (iRet === -1) {
      alert("您还未安装过插件,请安装WebComponentsKit.exe插件!");
      return;
    }
    initPlugin();
  }
  //插件初始化
  function initPlugin() {
    var that = this;
    WebVideoCtrl.I_InitPlugin('100%', '100%', {
      szContainerID: 'divPlugin',
      bWndFull: true, //是否支持单窗口双击全屏,默I_CheckPluginInstall
      iWndowType: 1, // 窗口数量n*n
      szColorProperty: 'plugin-background:000000; sub-background:000000; sub-border:000000; sub-border-select:000000',
      // bDebugMode: true,
      cbSelWnd: function (xmlDoc) {
      },
    });
    // 绑定的dom名称
    WebVideoCtrl.I_InsertOBJECTPlugin('divPlugin');
    clickLogin(companyVideoData);
  }
  function clickLogin(data) {
    var that = this;
    WebVideoCtrl.I_Login(
      data.IP,
      1,
      data.Port,
      data.Username,
      data.Password,
      {
        async: false,
        success: function (xmlDoc) {
          console.log("开始预览", that.cName); //不能删除
          that.getChannelInfo();
        },
        error: function () {
          console.log("login error");
        },
      }
    );
  }
  //获取通道
  function getChannelInfo() {
    var that = this;
    // this.szIP = companyVideoData.IP
    // 模拟通道
    WebVideoCtrl.I_GetAnalogChannelInfo(that.companyVideoData.IP, {
      async: false,
      success: function (xmlDoc) {
        var oChannels = $(xmlDoc).find("VideoInputChannel");
        // nAnalogChannel = oChannels.length;
        that.initPlay();
        console.log("获取模拟通道成功!", that.cName)
      },
      error: function () {
        console.log("获取模拟通道失败!"+WebVideoCtrl.I_GetLastError())
      },
    });
    // 数字通道
    WebVideoCtrl.I_GetDigitalChannelInfo(that.companyVideoData.IP, {
      async: false,
      success: function (xmlDoc) {
        var oChannels = $(xmlDoc).find("InputProxyChannelStatus");
        that.initPlay();
        // that.$emit("func", oChannels); //获取数字通道传给父组件
        console.log("获取数字通道成功!")
      },
      error: function () {
        WebVideoCtrl.I_GetLastError();
        console.log("获取数字通道失败!"+WebVideoCtrl.I_GetLastError())
      },
    });
    // 零通道
    WebVideoCtrl.I_GetZeroChannelInfo(that.companyVideoData.IP, {
      async: false,
      success: function (xmlDoc) {
        var oChannels = $(xmlDoc).find("ZeroVideoChannel");
          console.log("获取零通道成功!")
      },
      error: function () {
        console.log("获取零通道失败!"+WebVideoCtrl.I_GetLastError())
      },
    });
  }
  //初始化视频,为了让用户进来就可以看到视频播放
  function initPlay() {
    let szIP = companyVideoData.IP; //ip地址
    var iStreamType = 1;
    // 目前只需要显示一个通道
    var iChannelID = parseInt(1, 10);
    WebVideoCtrl.I_StartRealPlay(szIP, {
      iStreamType: iStreamType,
      iChannelID: iChannelID,
      iWndIndex: 0,
    });
    WebVideoCtrl.I_ChangeWndNum(1); //分屏
  }
  // 点击查看具体哪个监控
  function startRealPlay(oChannels) {
    let that = this;
    let szIP = companyVideoData.IP; //ip地址
    let iChannelID = oChannels; //播放通道号
    var iStreamType = 1;
    var oWndInfo = WebVideoCtrl.I_GetWindowStatus(0);
    if (oWndInfo != null) {
      // 已经在播放了,先停止
      WebVideoCtrl.I_Stop();
    }
    WebVideoCtrl.I_StartRealPlay(szIP, {
      iStreamType: iStreamType,
      iChannelID: iChannelID,
    });
  }
</script>
</html>

3.组件中调用并传输数据

<template>
  <div class="video-player">
    <iframe ref="iframe" class="divPlugin" :src="iframeSrc" frameborder="0"></iframe>
  </div>
</template>
<script>
export default {
  props: {
    //从父组件传来的数据,IP、用户名、密码、端口号
    companyVideoData: {
      type: Object,
    },
    //分屏数量
    videoType: Number,
    // 相机名称
    cName: String
  },
  data() {
    return {
      // 分割线
      iframeWin: {},
      iframeSrc: 'iframe.html'
    };
  },
  created() {},
  mounted() {
    // this.videoInitPlugin();
    window.addEventListener('message', this.handleMessage)
    this.iframeWin = this.$refs.iframe.contentWindow
  },
  methods: {
    async handleMessage (event) {
      const data = event.data
      switch (data.cmd) {
        case 'run':
          if (data.params.success) {
            // 调用报名方法
            await this.sendMessage()
          } else {
            console.log('视频启动失败')
          }
          break
      }
    },
    sendMessage () {
      // 外部vue向iframe内部传数据
      this.iframeWin.postMessage({
        cmd: 'getFormJson',
        params: {
          ...this.companyVideoData
        }
        }, '*')
    }
  }
};
</script>
<style  scoped>
.video-player {
  width: 100%;
  height: 100%;
}
.divPlugin {
  width: 100%;
  height: 100%;
  color: red;
  /* display: flex; */
  background: gray;
  /* border: 1px solid black; */
  justify-content: center;
  align-items: center;
  font-size: 18px;
}
.down {
  width: 100%;
  height: 100%;
  color: red;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 18px;
}
.down a {
  color: red;
}
</style>

4.父组件调用子组件

// 此处cName是因为我需要for循环显示两个视频,如果只要显示一个,不需要传入cName,companyVideoData传入你想要的数据即可
<!-- 海康 -->
<div class="cBox" v-if="displayModeId == 1">
  <hai-kang-camara
    :cName="i==0 ? 'icamera' : 'vcamera'"
    :companyVideoData="i==0 ? vcamera : icamera"
    :videoType = 1
  ></hai-kang-camara>
</div>


// 登录所需的参数
vcamera: {
   IP: "192.168.1.64",
   Port: 80,
   Username: "admin",
   Password: "xxxxxxxx",
 },
icamera: {
  IP: "192.168.1.64",
  Port: 80,
  Username: "admin",
  Password: "xxxxxxxx"
},
 // videoType要展示的通道数量
 videoType: 1

5.效果

在这里插入图片描述

Logo

前往低代码交流专区

更多推荐