- <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>