Newer
Older
Nanping_sponge_HHDP / src / components / videoHK / index.vue
@liyingjing liyingjing on 25 Oct 2023 10 KB 海绵大屏
<template>
  <div id="index">
    <div
      ref="playWnd"
      :id="containerId"
      class="playWnd"
      v-html="AllData.oWebControl === null ? AllData.playText : ''"
    ></div>
  </div>
</template>

<script setup name="index">
import { ref, reactive, toRefs, onMounted } from "vue";
const props = defineProps({
  // 内网、公网 4个配置
  appkey: {
    type: String,
    default: () => "25124952",
  },
  secret: {
    type: String,
    default: () => "aJOYWAt8CJabjjA1Ekeq",
  },
  ip: {
    type: String,
    default: () => "113.57.101.104",
  },
  port: {
    type: Number,
    default: () => 8888,
  },
  // 视频布局
  layout: {
    type: String,
    default: () => "1x1",
  },
  // 初始播放模式:0-预览,1-回放
  playMode: {
    type: Number,
    default: () => 0,
  },
  // 是否显示工具栏,0-不显示,非0-显示
  showToolbar: {
    type: Number,
    default: () => 1,
  },
  // 工具栏按钮
  toolBarButtonIDs: {
    type: String,
    default: () => "4098,4097",
  },
  // 是否显示智能信息(如配置移动侦测后画面上的线框),0-不显示,非0-显示
  showSmart: {
    type: Number,
    default: () => 1,
  },
  // 自定义工具条按钮
  buttonIDs: {
    type: String,
    default: () => "0,16,256,257,258,259,512,260,515,516,517,768,769",
  },
  // 相机编号
  cameraIndexCode: {
    type: [String, Number],
  },
  // 视频播放容器id
  containerId: {
    type: String,
    default: () => "playWnd",
  },
  // 默认打开的视频
  defaultList: {
    type: Array,
    default: () => [],
  },
});

const AllData = reactive({
  oWebControl: null,
  plugKey: "",
  // 视频相关参数
  videoParams: {
    cameraIndexCode: "", //监控点编号
    streamMode: 0, //主子码流标识:0-主码流,1-子码流
    transMode: 1, //传输协议:0-UDP,1-TCP
    gpuMode: 0, //是否启用GPU硬解,0-不启用,1-启用
    wndId: 1, //播放窗口序号
  },
  videoWidth: null,
  videoHeight: null,
  playText: "启动中...",
  initCount: 0, // 启动次数
  href: "",
});
// 视频容器的ref对象
const playWnd = ref(null);

// 监听视频编码的改变(单个视频编码)
watch(
  () => props.cameraIndexCode,
  (val) => {
    if (props.cameraIndexCode) {
      AllData.videoParams.cameraIndexCode = props.cameraIndexCode.trim();
      AllData.videoParams.wndId = -1;
      debugger;
      if (AllData.oWebControl) {
        previewVideo();
      } else {
        createdVideo();
      }
    }
  }
);
// 监听视频编码数组的改变(批量视频编码)
watch(
  () => props.defaultList,
  (val) => {
    if (props.defaultList.length > 0) {
      PiLiangpreviewVideo();
    }
  }
);
// 监听布局修改
watch(
  () => props.layout,
  (val) => {
    setLayoutFunc();
  }
);

// 创建播放实例
const initPlugin = (callback) => {
  AllData.oWebControl = new WebControl({
    szPluginContainer: props.containerId, // 指定容器id
    iServicePortStart: 15900,
    iServicePortEnd: 15909,
    szClassId: "23BF3B0A-2C56-4D97-9C03-0CB103AA8F11", // 用于IE10使用ActiveX的clsid
    // 创建WebControl实例成功
    cbConnectSuccess: () => {
      AllData.oWebControl
        .JS_StartService("window", {
          // WebControl实例创建成功后需要启动服务
          dllPath: "./VideoPluginConnect.dll",
        })
        .then(() => {
          // 启动插件服务成功
          AllData.oWebControl.JS_SetWindowControlCallback({
            // 设置消息回调
            cbIntegrationCallBack: cbIntegrationCallBack,
          });
          AllData.oWebControl
            .JS_CreateWnd(props.containerId, AllData.videoWidth, AllData.videoHeight)
            .then(() => {
              getVersion(callback);
            });
        });
    },
    cbConnectError: () => {
      // 创建WebControl实例失败
      AllData.oWebControl = null;
      AllData.playText = "插件未启动,正在尝试启动,请稍候...";
      WebControl.JS_WakeUp("VideoWebPlugin://"); // 程序未启动时执行error函数,采用wakeup来启动程序
      AllData.initCount++;
      if (AllData.initCount < 3) {
        setTimeout(() => {
          initPlugin();
        }, 3000);
      } else {
        AllData.playText = `
              插件启动失败,请检查插件是否安装!
              <a href=${AllData.href} type="primary" download="视频插件.exe" style='color:#4194fc'>下载地址</a>`;
      }
    },
    cbConnectClose: () => {
      AllData.oWebControl = null;
    },
  });
};

// HK插件控制监听的消息回调
const cbIntegrationCallBack = (oData) => {
  console.log(oData);
  if (oData.responseMsg.type == 6) {
    // 此时是当前画幅的数据
    console.log(
      `当前画面的画幅是` + oData.responseMsg.msg.layout,
      oData.responseMsg.msg.wndNum
    );
    localStorage.setItem("HKlayout", oData.responseMsg.msg.layout);
    localStorage.setItem("HKwndNum", oData.responseMsg.msg.wndNum);
  }
};

// 初始化
const init = (callback) => {
  getPubKey(() => {
    AllData.oWebControl
      .JS_RequestInterface({
        funcName: "init",
        argument: JSON.stringify({
          appkey: props.appkey, //API网关提供的appkey
          secret: setEncrypt(props.secret), //API网关提供的secret
          ip: props.ip, //API网关IP地址z
          playMode: props.playMode, //播放模式(决定显示预览还是回放界面)
          port: props.port, //端口
          snapDir: "C:\\SnapDir", //抓图存储路径
          videoDir: "C:\\VideoDir", //紧急录像或录像剪辑存储路径
          layout: props.layout, //布局
          enableHTTPS: 1, //是否启用HTTPS协议
          encryptedFields: "secret", //加密字段
          showToolbar: props.showToolbar, //是否显示工具栏
          toolBarButtonIDs: props.toolBarButtonIDs,
          showSmart: props.showSmart, //是否显示智能信息
          buttonIDs: props.buttonIDs, //自定义工具条按钮
          protocol: "hls",
        }),
      })
      .then(() => {
        AllData.videoWidth = playWnd.value.offsetWidth;
        AllData.videoHeight = playWnd.value.offsetHeight;
        // 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
        AllData.oWebControl.JS_Resize(AllData.videoWidth, AllData.videoHeight);
        // 判断当前cameraIndexCode中是否有数据 有数据的话就直接进行播放
        if (props.defaultList.length > 0) {
          // 批量渲染
          PiLiangpreviewVideo();
        } else if (props.cameraIndexCode.length > 0) {
          // 单独渲染
          AllData.videoParams.cameraIndexCode = props.cameraIndexCode.trim();
          previewVideo();
        }
        if (callback) {
          callback();
        }
      });
  });
};
// 获取公钥
const getPubKey = (callback) => {
  const params = {
    funcName: "getRSAPubKey",
    argument: JSON.stringify({ keyLength: 1024 }),
  };
  AllData.oWebControl.JS_RequestInterface(params).then((res) => {
    if (res.responseMsg.data) {
      AllData.plugKey = res.responseMsg.data;
      callback();
    }
  });
};
// 视频流RSA加密
const setEncrypt = (value) => {
  const encrypt = new JSEncrypt();
  encrypt.setPublicKey(AllData.plugKey);
  return encrypt.encrypt(value);
};

// 视频预览
const previewVideo = () => {
  console.log(AllData.videoParams, "单个视频播放");
  AllData.oWebControl.JS_RequestInterface({
    funcName: "startPreview",
    argument: JSON.stringify(AllData.videoParams),
  });
};
// 批量预览
const PiLiangpreviewVideo = () => {
  console.log(props.defaultList, "批量批量批量");
  AllData.oWebControl.JS_RequestInterface({
    funcName: "startMultiPreviewByCameraIndexCode",
    argument: {
      list: props.defaultList,
    },
  });
};
// 显示全屏
const showFullScreen = () => {
  AllData.oWebControl.JS_RequestInterface({
    funcName: "setFullScreen",
  });
};
// 退出全屏
const exitFullScreen = () => {
  AllData.oWebControl.JS_RequestInterface({
    funcName: "exitFullScreen",
  });
};
const windowScroll = () => {
  if (AllData.oWebControl != null) {
    AllData.oWebControl.JS_Resize(AllData.videoWidth, AllData.videoHeight);
  }
};
// 获取HK父节点的宽高
const windowResize = () => {
  AllData.videoWidth = playWnd.value.offsetWidth;
  AllData.videoHeight = playWnd.value.offsetHeight;
  if (AllData.oWebControl) {
    AllData.oWebControl.JS_Resize(AllData.videoWidth, AllData.videoHeight);
  }
};
// 销毁海康插件
const destroyeWnd = () => {
  if (AllData.oWebControl) {
    AllData.oWebControl.JS_HideWnd();
    AllData.oWebControl.JS_Disconnect().then(() => {});
  }
};
// 获取海康插件版本号
const getVersion = (callback) => {
  if (AllData.oWebControl) {
    AllData.oWebControl
      .JS_RequestInterface({
        funcName: "getVersion",
      })
      .then((res) => {
        if (res.responseMsg.code === 0 && res.responseMsg.data === "V1.5.1") {
          //JS_CreateWnd创建视频播放窗口,宽高可设定
          init(callback); // 创建播放实例成功后初始化
          console.log("启动插件成功!");
        } else {
          destroyeWnd();
          AllData.playText = `
              插件版本不正确,请重新下载版本安装覆盖!
              <a href=${AllData.href} type="primary" download="视频插件.exe" style='color:#4194fc'>下载地址</a>`;
        }
      });
  }
};
// 切换布局
const setLayoutFunc = () => {
  AllData.oWebControl.JS_RequestInterface({
    funcName: "setLayout",
    argument: {
      layout: props.layout, // 窗口布局
    },
  });
  if (props.layout != "1x1") {
    // 先清除所有画面
    clearShiPing();
  }
};
// 销毁当前正在播放的所有画面
const clearShiPing = () => {
  AllData.oWebControl.JS_RequestInterface({
    funcName: "stopAllPreview",
  });
  AllData.videoParams.wndId = 0;
};
// 初始化
const createdVideo = () => {
  initPlugin(() => {});
};
onMounted(() => {
  // 创建实例
  initPlugin();

  // 监听resize事件,使插件窗口尺寸跟随DIV窗口变化
  window.addEventListener("resize", windowResize());
  // // 监听滚动条scroll事件,使插件窗口跟随浏览器滚动而移动
  window.addEventListener("scroll", windowResize());
});
onBeforeUnmount(() => {
  if (AllData.oWebControl) {
    AllData.oWebControl.JS_HideWnd();
    AllData.oWebControl
      .JS_DestroyWnd({
        funcName: "destroyeWnd",
      })
      .then(() => {});
  }
  document.removeEventListener("resize", windowResize());
  document.removeEventListener("scroll", windowScroll());
});
</script>

<style lang="scss" scoped>
#index {
  width: 100%;
  height: 100%;
  .playWnd {
    width: 100%;
    height: 100%;
  }
}
</style>