Newer
Older
KaiFengPC / src / components / videoHK / playBack.vue
@鲁yixuan 鲁yixuan on 19 Aug 9 KB updata
<template>
  <!-- 海康监控视频 回放视频 -->
  <div class="videoHKPageBack">
    <div ref="playWnd" :id="containerId" class="playWnd" v-html="AllData.oWebControl === null ? AllData.playText : ''"></div>
  </div>
</template>

<script setup name="index">
import { ref, reactive, 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: () => 'playWndHKBK',
  },
  startTimeStamp: {
    type: String,
    default: () => '2024-01-10 12:20:30',
  },
  endTimeStamp: {
    type: String,
    default: () => '2024-01-10 15:20:30',
  },
});

const AllData = reactive({
  oWebControl: null,
  plugKey: '',
  // 视频相关参数
  videoParams: {
    cameraIndexCode: '', //监控点编号
    startTimeStamp: props.startTimeStamp, //录像搜索开始时间戳,单位:秒
    endTimeStamp: props.endTimeStamp, //录像结束开始时间戳,单位:秒
    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;
      if (AllData.oWebControl) {
        previewVideo();
      } else {
        createdVideo();
      }
    }
  }
);
// 监听布局修改
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(() => {
            init(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: 1, //播放模式(决定显示预览还是回放界面)
          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);
        // 单独渲染
        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.videoParams.startTimeStamp = new Date(AllData.videoParams.startTimeStamp.replace('-', '/').replace('-', '/')).getTime(); //回放开始时间戳,必填
  AllData.videoParams.endTimeStamp = new Date(AllData.videoParams.endTimeStamp.replace('-', '/').replace('-', '/')).getTime(); //回放结束时间戳,必填
  AllData.oWebControl.JS_RequestInterface({
    funcName: 'startPlayback',
    argument: JSON.stringify(AllData.videoParams),
  });
};

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 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>
.videoHKPageBack {
  width: 100%;
  height: 100%;
  .playWnd {
    width: 100%;
    height: 100%;
  }
}
</style>