vue3引入海康监控视频组件并实现非分屏需求一个页面同时预览多个监控视频;

发布于:2025-07-05 ⋅ 阅读:(21) ⋅ 点赞:(0)

海康监控视频非分屏需求,一个页面引用多个视频组件;

js文件位置

在这里插入图片描述

index.html 引入js文件

   //根据自己路径引入哈
  <script src="static/haiKangWeb3.0/jquery-1.7.1.min.js"></script>
  <script type="text/javascript" id="videonode" src="static/haiKangWeb3.0/webVideoCtrl.js"></script>

在这里插入图片描述

新建子组件videoMonitorings.vue

//子组件
<template>
  <div class="video">
    <div :id="videoId" class="plugin"/>
  </div>
</template>

<script>
import {WebVideo} from "../../../public/static/haiKangWeb3.0/webVideo.js";
import {message} from "@/utils/message";
import {
  reactive,
  onMounted,
  onBeforeUnmount,
  onUnmounted,
  toRefs,
  ref,
  watch
} from "vue";

export default {
  name: "index",
  props: {
    videoId: {
      type: String
    },
    hkvInfo: {
      type: Object || Array,
      require: true
    },
  },
  // emits:['changeFlag'],
  setup(props,{emit}) {

    const {dataList} = toRefs(props);

    const hkvInfo = ref({});

    const videoId = ref();

    const channels = ref([])

    const state = reactive({
      webVideo: "",
      web: {},
    });


    watch(props.hkvInfo, (newVal, oldvalue) => {
      if (newVal) {
        console.log('newVal', newVal)
        const web = new WebVideo();
        hkvInfo.value = newVal
        videoId.value = newVal.id;
        let t = newVal.loadingTime || 1000
        setTimeout(() => {
          initS();
        }, t)
      } else {
        initS();
      }
    }, {
      deep: true,
      immediate: true,
    })


    const initS = () => {
      // 初始化
      WebVideoCtrl.I_InitPlugin({
        bWndFull: true, //是否支持单窗口双击全屏,默认支持 true:支持 false:不支持
        iWndowType: 1,// 画面分割数 1 就是1*1   2就是2*2
        cbSelWnd: function (xmlDoc) {
          //此属性是窗口分割切换窗口时触发
          //clickStartRealPlay();
          // console.log("当前选择的窗口编号是1");
        },
        cbInitPluginComplete: function () {
          WebVideoCtrl.I_InsertOBJECTPlugin(videoId.value).then(
            () => {
              // 检查插件是否最新
              WebVideoCtrl.I_CheckPluginVersion().then((bFlag) => {
                if (bFlag) {
                  let str = "检测到新的插件版本,双击开发包目录里的HCWebSDKPlugin.exe升级!"
                  message(str, {
                    type: "warning"
                  });
                }
              });
            },
            () => {
              let str1 = "插件初始化失败,请确认是否已安装插件;如果未安装,请双击开发包目录里的HCWebSDKPlugin.exe安装!";
              message(str1, {
                type: "warning"
              });
            }
          );
        },
      });
      setTimeout(() => {
        let cw = Math.round(document.body.clientWidth / 1920);
        let ch = Math.round(document.body.clientHeight / 1080);
        let width = parseInt((hkvInfo.value.width * cw), 10);
        let height = parseInt((hkvInfo.value.height * ch), 10);
        if (height <= 200) {
          height = 200;
        }
        if (height <= 200) {
          height = 200;
        }
        let w1 = (window.innerWidth - document.getElementById(videoId.value).offsetLeft) - 1500;
        let w2 = document.getElementById(videoId.value).clientHeight;
        console.log('00000===>', width, height);
        // 对窗口大小重新规划
        WebVideoCtrl.I_Resize(
          width,
          height
        );
        setVideoWindowResize(videoId.value, width, height);
        clickLogin();
      }, 2000);
    }
    // 根据设备宽高和windowchange设置窗口大小
    const setVideoWindowResize = (pid, width, height) => {
      document.getElementById(pid).style.width = width + 'px';
      document.getElementById(pid).style.height = height + 'px';
    }

    // 登录
    const clickLogin = () => {
      var szIP = hkvInfo.value.ip,
        szPort = hkvInfo.value.port,
        szUsername = hkvInfo.value.username,
        szPassword = hkvInfo.value.password;
      const iRet = WebVideoCtrl.I_Login(szIP, 1, szPort, szUsername, szPassword, {
        timeout: 3000,
        success: function (xmlDoc) {
          setTimeout(function () {
            setTimeout(function () {
              getChannelInfo();
            }, 1000);
            getDevicePort();
          }, 10);
        },
        error: function (err) {
          console.log("登录-err===>", err);
        },
      });

      if (iRet === -1) {
        console.log(this.szDeviceIdentify + " 已登录过!");
        // 登录过直接进行预览
        clickStartRealPlay();
      }
    }

    const getDevicePort = () => {
      var szDeviceIdentify = hkvInfo.value.ip;
      if (null == szDeviceIdentify) {
        return;
      }
      WebVideoCtrl.I_GetDevicePort(szDeviceIdentify).then((oPort) => {
        console.log("152获取端口", oPort);
      });
    }

    const getChannelInfo = () => {
      let that = this;
      var szDeviceIdentify = hkvInfo.value.ip + '_' + hkvInfo.value.port;

      if (null == szDeviceIdentify) {
        return;
      }
      console.log('szDeviceIdentify==============>', szDeviceIdentify);
      // 模拟通道
      WebVideoCtrl.I_GetAnalogChannelInfo(szDeviceIdentify, {
        success: function (xmlDoc) {
          clickStartRealPlay();
        },
        error: function (oError) {
          console.log(szDeviceIdentify + "模拟通道", oError.errorCode, oError.errorMsg);
        }
      });

      // 数字通道
      WebVideoCtrl.I_GetDigitalChannelInfo(szDeviceIdentify, {
        success: function (xmlDoc) {
          clickStartRealPlay();
        },
        error: function (oError) {
          console.log(szDeviceIdentify + " 数字通道", oError.errorCode, oError.errorMsg);
        }
      });
    }

    // 开始预览
    const clickStartRealPlay = (iStreamType) => {
      var g_iWndIndex = 0;
      var oWndInfo = WebVideoCtrl.I_GetWindowStatus(g_iWndIndex) || null;
      var szDeviceIdentify = hkvInfo.value.ip + '_' + hkvInfo.value.port,
        iChannelID = 1,
        bZeroChannel = false;
      if ("undefined" === typeof iStreamType) {
        iStreamType = 1;
      }
      if (null == szDeviceIdentify) {
        return;
      }
      var startRealPlay = function () {
        WebVideoCtrl.I_StartRealPlay(szDeviceIdentify, {
          iStreamType: iStreamType,
          iChannelID: iChannelID,
          bZeroChannel: bZeroChannel,
          success: function () {
            WebVideoCtrl.I_Logout(szDeviceIdentify);
            console.log("开始预览成功!");
          },
          error: function (oError) {
            // that.$message.error(szDeviceIdentify+"开始预览失败!");
            console.log(szDeviceIdentify + "开始预览失败!");
          },
        });
      };

      if (oWndInfo != null) {// 已经在播放了,先停止
        WebVideoCtrl.I_Stop({
          success: function () {
            startRealPlay();
          }
        });
      } else {
        startRealPlay();
      }
    }

    // 停止预览
    const clickStopRealPlay = () => {
      WebVideoCtrl.I_Stop({
        success: function () {
          console.log("停止预览成功!");
        },
        error: function (oError) {
          console.log(" 停止预览失败!");
        },
      });
    }

    const loginOut = () => {
      const szDeviceIdentify = hkvInfo.value.ip + "_" + hkvInfo.value.port;
      WebVideoCtrl.I_Logout(szDeviceIdentify);
    }

    const stopAllPlay = () => {
      WebVideoCtrl.I_StopAllPlay();
    }

    const breakDom = () => {
      WebVideoCtrl.I_DestroyPlugin()
    }

    const viewReload = () => {
      window.location.reload()
    }

    onMounted(() => {

    });

    onBeforeUnmount(() => {
      loginOut();
      stopAllPlay();
      window.removeEventListener(viewReload());
    });

    onUnmounted(() => {
      setTimeout(() => {
        breakDom();
      }, 100)
    })

    return {
      loginOut,
      stopAllPlay,
      breakDom,
      hkvInfo,
      initS,
      viewReload,
      channels,
      clickLogin,
      clickStopRealPlay,
      clickStartRealPlay,
      setVideoWindowResize,
      getChannelInfo,
      getDevicePort,
      ...toRefs(state)
    };
  }
};
</script>

<style scoped lang="scss">
.video {
  width: 100%;
  height: 100%;
  //position: relative;
  ::v-deep(#divPlugin) {
    width: 100%;
    height: 100%;
    //position: absolute;
    z-index: -1 !important;
  }

  ::v-deep(#divPlugin1) {
    width: 100%;
    height: 100%;
    //position: absolute;
    z-index: -1 !important;
  }

  ::v-deep(#divPlugin2) {
    width: 100%;
    height: 100%;
    //position: absolute;
    z-index: -1 !important;
  }

  ::v-deep(#divPlugin3) {
    width: 100%;
    height: 100%;
    //position: absolute;
    z-index: -1 !important;
  }

  ::v-deep(#divPlugin4) {
    width: 100%;
    height: 100%;
    //position: absolute;
    z-index: -1 !important;
  }
}
</style>

父组件index.vue 引用 子组件

//index.vue
<template>
  <div class="main-content">
    <div class="video-content">
    //单个使用
      <!--      <div class="canvas-contaniner"   >-->
      <!--        <div class="videobox">-->
      <!--          <videoMonitorings :hkvInfo="dataList.hkvInfo01" class="video" :videoId="dataList.hkvInfo01.id" ></videoMonitorings>-->
      <!--        </div>-->
      <!--      </div>-->
      //多个使用
      <div class="canvas-contaniner" v-for="(item,index) in dataListRef" :key="index">
        <div class="videobox">
          <videoMonitorings :hkvInfo="item" class="video" :videoId="item.id"></videoMonitorings>
        </div>
      </div>
    </div>
  </div>
</template>
<script setup lang="ts">

import {ref, reactive, onMounted, onBeforeUnmount} from "vue";

import {WebVideo} from "../../../public/static/haiKangWeb3.0/webVideo.js";

import videoMonitorings from "./videoMonitorings.vue";

const loading = ref(false);

const dialogVisible = ref(false);

/*
* @以上hkList配置中 注意 loadingTime 和 id;其中loadingTime 建议和上一个时间间隔4S以上,id是动态加载生成填充的DOM树结构;
* 如果间隔时间不够 或DOM的ID一样 可能出现画面加载不出来、画面覆盖重叠等情况;通过配置这2个参数可以避免这样多个摄像头只需要 增加 hkList的配置项即可;
* */
//填入自己ip地址
const dataListRef = ref([
  {
    ip: "", //IP地址
    port: "", //端口号
    username: "",
    password: "",
    iChannelID: 1,
    loadingTime: "1000",
    width: "805",
    height: "375",
    type: "camera01",
    id: "divPlugin1",
  },
  {
    ip: "", //IP地址
    port: "", //端口号
    username: "",
    password: "",
    deviceport: "",
    iChannelID: 1,//通道ID
    loadingTime: "5000",
    width: "805",
    height: "375",
    type: "camera02",
    id: "divPlugin2",
  },
  {
    ip: "", //IP地址
    port: "", //端口号
    username: "",
    password: "",
    iChannelID: 1,
    loadingTime: "10000",
    width: "805",
    height: "375",
    type: "camera03",
    id: "divPlugin3",
  },
  {
    ip: "", //IP地址
    port: "", //端口号
    username: "",
    password: "",
    iChannelID: 1,
    loadingTime: "15000",
    width: "805",
    height: "375",
    type: "camera04",
    id: "divPlugin4",
  }
])


//单个.
const dataList = ref({
  hkvInfo01: {
    ip: "", //IP地址
    port: "", //端口号
    username: "",
    password: "",
    deviceport: "",
    iChannelID: 1,//通道ID
    loadingTime: "1000",// 多视频窗口睡眠加载时长。同时多个加载会卡死或不显示
    width: "805",
    height: "375",
    type: "camera01",
    id: "divPlugin1",
  },
  hkvInfo02: {
    ip: "", //IP地址
    port: "", //端口号
    username: "",
    password: "",
    iChannelID: 1,
    loadingTime: "5000",
    width: "805",
    height: "375",
    type: "camera02",
    id: "divPlugin2",
  },
});

onMounted(() => {

})
</script>
<style lang="scss" scoped>
.main-content {
  margin: 24px 24px 0 !important;
}

.video-content {
  display: flex;
  justify-content: flex-start;
  flex-wrap: wrap;
  position: relative;
  width: 100%;
  height: 85vh;

  .canvas-contaniner {
    width: 49%;
    height: 49%;
    padding: 10px;
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 3px;
    overflow: hidden;
    //background: red;
  }

  .videobox {
    display: flex !important;
    justify-content: center;
    align-items: center !important;
    width: 100% !important;
    height: 100% !important;
    font-size: 30px;
    color: #fff;
    position: relative !important;
    //left: 20px;
    background: black;
    //border: 1px solid red;
    overflow: hidden;
    //background-color:black;
    .video {
      width: 100% !important;
      height: 100% !important;
      object-fit: fill;
      background-color: #000;
    }
  }

  .loading {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 100%;
    font-size: 30px;
    color: #fff;
    position: absolute;
    background: black;

  }
}

</style>

运行效果图如下:
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到