SpringBoot+Vue+iSecure Center(海康综合安防管理平台)实现视频预览
作者:互联网
场景
SpringBoot+Vue+HIKVSION实现摄像头多选并多窗口预览(插件版):
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/121180769
上面可通过单个摄像头的ip、端口、用户名、密码等参数实现单个摄像头预览。
但是缺点是如果是插件版的摄像头视频对接,需要将浏览器切换成兼容模式或者使用IE浏览器进行预览。
但是如果将摄像头添加到海康威视的综合安防管理平台(iSecure Center上),则可以不用切换兼容模式进行
视频预览。
对接的文档以及示例代码可以去海康威视官网寻找和下载
注意选择对应的版本,版本查看方式在安防平台中点击右上角菜单的按钮,选择关于
然后点击关于就可以看到版本
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。
实现
1、下载示例代码之后找到demo下的preview的html,这里以1.1.0为例,不同版本代码目录可能不同。
2、打开该预览demo页面发现预览需要一些参数appkey、secret、API网关地址IP、监控点编号等关键信息。
3、appkey等调用接口认证的相关参数获取。
在安防平台对应ip的8001端口进入运行管理中心,或者可以直接通过安防平台的关于直接点击跳转
然后状态监控-运行管理中心-API网关-参数配置-API管理
然后新建合作方,就可以获取到appkey和secret
4、监控点获取
综合安防管理平台右上角点击菜单选择系统管理-设备管理-视频监控-监控点
点击每个摄像头的编辑按钮即可以看到监控点编号
5、视频预览demo运行
首先确保这个监控点在安防平台本身是能直接预览的,会提示你安装插件,安装完插件之后可能需要重新浏览器或者电脑。
然后在预览htmldemo中配置以上的参数并进行预览测试。
6、在示例代码下能成功预览则进行VUE代码改造。
若依前后端分离版手把手教你本地搭建环境并运行项目:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108465662
上面在搭建起来前后端分离版的项目后,新建一个数据库用来存储监控点的编号信息等。
DROP TABLE IF EXISTS `bus_platform_surveillance_video`; CREATE TABLE `bus_platform_surveillance_video` ( `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '序号', `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '名称', `monitory_point_number` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '监控点编号', `area_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '位置', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 22 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '带有监控点编号的摄像头' ROW_FORMAT = Dynamic; SET FOREIGN_KEY_CHECKS = 1;
这里主要建了一个表用来存储摄像头监控点的编号以及坐标信息(业务需求)。
然后根据数据库生成后台代码,这里不再赘述,只需要简单的增删改查的接口。
7、前端代码
Vue的预览代码大部分就是参考其官方的预览html的demo进行的改造。
附官方预览html代码
<!doctype html> <html> <head> <title>预览Demo</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> html, body { padding: 0; margin: 0; } .playWnd { margin: 50px 0 0 100px; width: 600px; height: 400px; border: 1px solid red; } .cbInfoDiv { float: left; width: 500px; margin-left: 16px; border:1px solid #7F9DB9; } .cbInfo { height: 200px; padding: 5px; border: 1px solid #7F9DB9; overflow: auto; word-break: break-all; } .operate { margin-top: 24px; } .operate::after { content: ''; display: block; clear: both; } .operate .btns { height: 32px; } .module { float: left; width: 340px; min-height: 320px; margin-left: 16px; padding: 16px 8px; box-sizing: border-box; border: 1px solid #e5e5e5; } .module .item { margin-bottom: 4px; } .module .label { width: 150px; display: inline-block; vertical-align: middle; margin-right: 8px; text-align: right; } .module input[type="text"], .module select { box-sizing: border-box; display: inline-block; vertical-align: middle; margin-left: 0; width: 150px; min-height: 20px; } .module .btn { min-width: 80px; min-height: 24px; margin-top: 16px; margin-left: 158px; } </style> <body> <div id="playWnd" class="playWnd"></div> <div id="operate" class="operate"> <div class="module"> <div class="item"><span class="label">appkey:</span><input id="appkey" type="text"></div> <div class="item"><span class="label">secret:</span><input id="secret" type="text"></div> <div class="item"><span class="label">API网关IP地址:</span><input id="ip" type="text"></div> <div class="item"> <span class="label">是否启用HTTPS协议</span> <select id="isHttps" onchange="UpdateValue()" value="不启用"> <option value="0" selected>不启用</option> <option value="1">启用</option> </select> </div> <div class="item"><span class="label">API网关端口:</span><input id="port" value="80" type="text"></div> <div class="item"><span class="label">抓图存储路径:</span><input id="snapDir" type="text" value="D:\SnapDir"></div> <div class="item"> <span class="label">初始化布局:</span> <select id="layout" value="2x2"> <option value="1x1">1x1</option> <option value="2x2" selected>2x2</option> <option value="3x3">3x3</option> <option value="4x4">4x4</option> </select> </div> <div class="item"> <span class="label">加密字段:</span> <div style="display: inline-block; vertical-align: top;"> <label><input type="checkbox" value="secret" disabled checked>secret</label><br> <label><input class="encryptedFields" type="checkbox" value="appkey">appkey</label><br> <label><input class="encryptedFields" type="checkbox" value="ip">ip</label><br> <label><input class="encryptedFields" type="checkbox" value="snapDir">抓图路径</label><br> <label><input class="encryptedFields" type="checkbox" value="layout">布局</label> </div> </div> <div class="item"><button id="init" class="btn">初始化</button></div> </div> <div class="module"> <div class="item"><span class="label">监控点编号:</span><input id="cameraIndexCode" type="text"></div> <div class="item"> <span class="label">主子码流标识:</span> <select id="streamMode" value="0"> <option value="0">主码流</option> <option value="1">子码流</option> </select> </div> <div class="item"> <span class="label">传输协议:</span> <select id="transMode" value="1"> <option value="1">TCP</option> <option value="0">UDP</option> </select> </div> <div class="item"> <span class="label">是否启用GPU硬解:</span> <select id="gpuMode" value="0"> <option value="0">不启用</option> <option value="1">启用</option> </select> </div> <div class="item"><button id="startPreview" class="btn">预览</button></div> <div class="item"><button id="stopAllPreview" class="btn">停止全部预览</button></div> <div class="item"><button id="uninit" class="btn">反初始化</button></div> </div> <fieldset class="cbInfoDiv"> <legend>返回值信息</legend> <div id="cbInfo" class="cbInfo"></div> <button id="clear">清空</button> </fieldset> </div> </body> <script src="jquery-1.12.4.min.js"></script> <script src="jsencrypt.min.js"></script> <script src="jsWebControl-1.0.0.min.js"></script> <script type="text/javascript"> var oWebControl = null;// 插件对象 var bIE = (!!window.ActiveXObject || 'ActiveXObject' in window);// 是否为IE浏览器 var pubKey = ''; var iLastCoverLeft = 0; var iLastCoverTop = 0; var iLastCoverRight = 0; var iLastCoverBottom = 0; var initCount = 0; // 标签关闭 $(window).unload(function () { if (oWebControl != null){ oWebControl.JS_Disconnect().then(function(){}, function() {}); } }); // 窗口resize $(window).resize(function () { if (oWebControl != null) { oWebControl.JS_Resize(600, 400); setWndCover(); } }); // 滚动条scroll $(window).scroll(function () { if (oWebControl != null) { oWebControl.JS_Resize(600, 400); setWndCover(); } }); // 设置窗口遮挡 function setWndCover() { var iWidth = $(window).width(); var iHeight = $(window).height(); var oDivRect = $("#playWnd").get(0).getBoundingClientRect(); var iCoverLeft = (oDivRect.left < 0) ? Math.abs(oDivRect.left): 0; var iCoverTop = (oDivRect.top < 0) ? Math.abs(oDivRect.top): 0; var iCoverRight = (oDivRect.right - iWidth > 0) ? Math.round(oDivRect.right - iWidth) : 0; var iCoverBottom = (oDivRect.bottom - iHeight > 0) ? Math.round(oDivRect.bottom - iHeight) : 0; iCoverLeft = (iCoverLeft > 600) ? 600 : iCoverLeft; iCoverTop = (iCoverTop > 400) ? 400 : iCoverTop; iCoverRight = (iCoverRight > 600) ? 600 : iCoverRight; iCoverBottom = (iCoverBottom > 400) ? 400 : iCoverBottom; if (iLastCoverLeft != iCoverLeft) { console.log("iCoverLeft: " + iCoverLeft); iLastCoverLeft = iCoverLeft; oWebControl.JS_SetWndCover("left", iCoverLeft); } if (iLastCoverTop != iCoverTop) { console.log("iCoverTop: " + iCoverTop); iLastCoverTop = iCoverTop; oWebControl.JS_SetWndCover("top", iCoverTop); } if (iLastCoverRight != iCoverRight) { console.log("iCoverRight: " + iCoverRight); iLastCoverRight = iCoverRight; oWebControl.JS_SetWndCover("right", iCoverRight); } if (iLastCoverBottom != iCoverBottom) { console.log("iCoverBottom: " + iCoverBottom); iLastCoverBottom = iCoverBottom; oWebControl.JS_SetWndCover("bottom", iCoverBottom); } } function UpdateValue() { var sel = document.getElementById("isHttps"); var selectedId = sel.selectedIndex; var v = sel.options[selectedId].value; if (0 == v) { document.getElementById("port").value = 80; } else { document.getElementById("port").value = 443; } } // 初始化插件 function initPlugin () { $("#init").attr('disabled', false); $("#startPreview").attr('disabled', false); $("#stopAllPreview").attr('disabled', false); $("#uninit").attr('disabled', false); oWebControl = new WebControl({ szPluginContainer: "playWnd", iServicePortStart: 15900, iServicePortEnd: 15909, cbConnectSuccess: function () { setCallbacks(); oWebControl.JS_StartService("window", { dllPath: "./VideoPluginConnect.dll" //dllPath: "./DllForTest-Win32.dll" }).then(function () { oWebControl.JS_CreateWnd("playWnd", 600, 400).then(function () { console.log("JS_CreateWnd success"); $("#init").attr('disabled', false); $("#startPreview").attr('disabled', false); $("#stopAllPreview").attr('disabled', false); $("#uninit").attr('disabled', false); }); }, function () { }); }, cbConnectError: function () { console.log("cbConnectError"); oWebControl = null; $("#playWnd").html("插件未启动,正在尝试启动,请稍候..."); WebControl.JS_WakeUp("VideoWebPlugin://"); initCount ++; if (initCount < 3) { setTimeout(function () { initPlugin(); }, 3000) } else { $("#playWnd").html("插件启动失败,请检查插件是否安装!"); } }, cbConnectClose: function () { console.log("cbConnectClose"); oWebControl = null; } }); } initPlugin(); // 获取公钥 function getPubKey (callback) { oWebControl.JS_RequestInterface({ funcName: "getRSAPubKey", argument: JSON.stringify({ keyLength: 1024 }) }).then(function (oData) { console.log(oData) if (oData.responseMsg.data) { pubKey = oData.responseMsg.data callback() } }) } // 设置窗口控制回调 function setCallbacks() { oWebControl.JS_SetWindowControlCallback({ cbIntegrationCallBack: cbIntegrationCallBack }); } // 推送消息 function cbIntegrationCallBack(oData) { showCBInfo(JSON.stringify(oData.responseMsg)); } // RSA加密 function setEncrypt (value) { var encrypt = new JSEncrypt(); encrypt.setPublicKey(pubKey); return encrypt.encrypt(value); } // 初始化 $("#init").click(function () { getPubKey(function () { var appkey = $("#appkey").val(); var secret = setEncrypt($("#secret").val()); var ip = $("#ip").val(); var port = parseInt($("#port").val()); var snapDir = $("#snapDir").val(); var layout = $("#layout").val(); var encryptedFields = ['secret']; var enableHttps = parseInt($("#isHttps").val()); $(".encryptedFields").each(function (index, item) { var $item = $(item); if ($item.prop('checked')) { var value = $item.val(); if (value !== 'secret') { encryptedFields.push(value); } // secret固定加密,其它根据用户勾选加密 if (value == 'ip') { ip = setEncrypt(ip) } if (value == 'appkey') { appkey = setEncrypt(appkey) } if (value == 'snapDir') { snapDir = setEncrypt(snapDir) } if (value == 'layout') { layout = setEncrypt(layout) } } }) encryptedFields = encryptedFields.join(","); if (!appkey) { showCBInfo("appkey不能为空!", 'error'); return } if (!$("#secret").val()) { showCBInfo("secret不能为空!", 'error'); return } if (!ip) { showCBInfo("ip不能为空!", 'error'); return } if (!$("#port").val()) { showCBInfo("端口不能为空!", 'error'); return } else if (!/^([0-9]|[1-9]\d{1,3}|[1-5]\d{4}|6[0-5]{2}[0-3][0-5])$/.test($("#port").val())) { showCBInfo("端口填写有误!", 'error'); return } console.log({ appkey: appkey, secret: secret, ip: ip, playMode: 0, // 预览 port: port, snapDir: snapDir, layout: layout, enableHTTPS: enableHttps, encryptedFields: encryptedFields }) oWebControl.JS_RequestInterface({ funcName: "init", argument: JSON.stringify({ appkey: appkey, secret: secret, ip: ip, playMode: 0, // 预览 port: port, snapDir: snapDir, layout: layout, enableHTTPS: enableHttps, encryptedFields: encryptedFields }) }).then(function (oData) { showCBInfo(JSON.stringify(oData ? oData.responseMsg : '')); }); }) }); // 视频预览 $("#startPreview").click(function () { var cameraIndexCode = $("#cameraIndexCode ").val(); var streamMode = +$("#streamMode").val(); var transMode = +$("#transMode").val(); var gpuMode = +$("#gpuMode").val(); if (!cameraIndexCode ) { showCBInfo("监控点编号不能为空!", 'error'); return } oWebControl.JS_RequestInterface({ funcName: "startPreview", argument: JSON.stringify({ cameraIndexCode : cameraIndexCode , streamMode: streamMode, transMode: transMode, gpuMode: gpuMode }) }).then(function (oData) { showCBInfo(JSON.stringify(oData ? oData.responseMsg : '')); }); }); // 停止预览 $("#stopAllPreview").click(function () { oWebControl.JS_RequestInterface({ funcName: "stopAllPreview" }).then(function (oData) { showCBInfo(JSON.stringify(oData ? oData.responseMsg : '')); }); }) // 反初始化 function uninit (cbFunc) { oWebControl.JS_RequestInterface({ funcName: "uninit" }).then(function (oData) { showCBInfo(JSON.stringify(oData ? oData.responseMsg : '')); cbFunc && cbFunc(); }); } $("#uninit").click(uninit) // 显示回调信息 function showCBInfo(szInfo, type) { if (type === 'error') { szInfo = "<div style='color: red;'>" + dateFormat(new Date(), "yyyy-MM-dd hh:mm:ss") + " " + szInfo + "</div>"; } else { szInfo = "<div>" + dateFormat(new Date(), "yyyy-MM-dd hh:mm:ss") + " " + szInfo + "</div>"; } $("#cbInfo").html(szInfo + $("#cbInfo").html()); } $("#clear").click(function() { $("#cbInfo").html(''); }) // 格式化时间 function dateFormat(oDate, fmt) { var o = { "M+": oDate.getMonth() + 1, //月份 "d+": oDate.getDate(), //日 "h+": oDate.getHours(), //小时 "m+": oDate.getMinutes(), //分 "s+": oDate.getSeconds(), //秒 "q+": Math.floor((oDate.getMonth() + 3) / 3), //季度 "S": oDate.getMilliseconds()//毫秒 }; if (/(y+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, (oDate.getFullYear() + "").substr(4 - RegExp.$1.length)); } for (var k in o) { if (new RegExp("(" + k + ")").test(fmt)) { fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); } } return fmt; } </script> </html>
改造成Vue的代码
8、首先是list页面用来查询所有摄像头的监控点编号信息。
<template> <div class="app-container"> <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px" > <el-form-item label="名称" prop="name"> <el-input v-model="queryParams.name" placeholder="请输入名称" clearable size="small" @keyup.enter.native="handleQuery" /> </el-form-item> <el-form-item> <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery" >搜索</el-button > <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> </el-form-item> </el-form> <el-row :gutter="10" class="mb8"> <el-col :span="1.5"> <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['runcontrolmange:surveillanceVideo:add']" >新增</el-button > </el-col> <el-col :span="1.5"> <el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate" v-hasPermi="['runcontrolmange:surveillanceVideo:edit']" >修改</el-button > </el-col> <el-col :span="1.5"> <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete" v-hasPermi="['runcontrolmange:surveillanceVideo:remove']" >删除</el-button > </el-col> <el-col :span="1.5"> <el-button type="success" plain icon="el-icon-setting" size="mini" :disabled="single" @click="videoChange" >预览</el-button > </el-col> </el-row> <el-table v-loading="loading" :data="videoList" @selection-change="handleSelectionChange" > <el-table-column type="selection" width="55" align="center" /> <el-table-column show-overflow-tooltip label="摄像头名称" align="center" prop="name" /> <el-table-column show-overflow-tooltip label="摄像头编号" align="center" prop="monitoryPointNumber" /> <el-table-column show-overflow-tooltip label="摄像头坐标" align="center" prop="areaName" /> <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <template slot-scope="scope"> <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['runcontrolmange:surveillanceVideo:edit']" >修改</el-button > <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['runcontrolmange:surveillanceVideo:remove']" >删除</el-button > </template> </el-table-column> </el-table> <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" /> <!-- 添加或修改识别用户对话框 --> <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> <el-form ref="form" :model="form" :rules="rules" label-width="120px"> <el-form-item label="摄像头名称" prop="name"> <el-input v-model="form.name" placeholder="请输入摄像头名称" /> </el-form-item> <el-form-item label="摄像头编号" prop="monitoryPointNumber"> <el-input v-model="form.monitoryPointNumber" placeholder="请输入摄像头编号" /> </el-form-item> <el-form-item label="摄像头位置" prop="coordinate"> <el-input v-model="lightPoint" placeholder="点击新增/更改摄像头坐标" @focus="onMap" /> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button type="primary" @click="submitForm">确 定</el-button> <el-button @click="cancel">取 消</el-button> </div> </el-dialog> <!-- 摄像头 --> <HkVideo ref="carVideo" :videoData="openVideoData[0].monitoryPointNumber" /> <!-- 地图 --> <videoMap ref="videoMap" @childEvent="parentEvent"></videoMap> </div> </template> <script> import { addVideo, updateVideo, delVideo, getVideoInfo, } from "@/api/runcontrolmange/HkVideo"; import HkVideo from "./components/HkVideo.vue"; import CarVideo from "../carVideo/component/video.vue"; import videoMap from "../carVideo/component/videoMap"; export default { name: "carHkVideo", components: { HkVideo, CarVideo, videoMap, }, data() { return { // 遮罩层 loading: false, // 选中数组 ids: [], // 非单个禁用 single: true, // 非多个禁用 multiple: true, // 显示搜索条件 showSearch: true, // 总条数 total: 0, // 表格数据 videoList: [], allVideoList: [], // 弹出层标题 title: "", // 是否显示弹出层 open: false, // 查询参数 queryParams: { pageNum: 1, pageSize: 10, }, // 表单参数 form: { coordinate: "", }, // 表单校验 rules: {}, dialogVisible: false, g_iWndIndex: 0, szInfo: "", rowList: {}, mySelectWnd: 0, //当前选中的窗口 g_bPTZAuto: false, iProtocol: 1, loginLoading: false, startPlayLoading: false, iStreamType: 1, bZeroChannel: false, iRtspPort: 0, ua: navigator.userAgent.toLocaleLowerCase(), browserType: null, // 预览摄像头的参数 openVideoData: [{monitoryPointNumber:''}], lightPoint: [], lightData: [], }; }, created() { this.getList(); }, mounted() {}, destroyed() {}, methods: { videoChange() { this.$refs.carVideo.videoChange() }, parentEvent(data) { this.form.siteX = data[0]; this.form.siteY = data[1]; this.lightPoint = `${this.form.siteX},${this.form.siteY}`; this.form.coordinate = this.lightPoint; }, onMap() { this.$refs.videoMap.dialogVisible = true; this.$refs.videoMap.init(); this.$refs.videoMap.coordinate = this.form.coordinate; this.$refs.videoMap.drawPoint([this.form.siteX, this.form.siteY]); }, getList() { getVideoInfo(this.queryParams).then((res) => { this.videoList = res.rows; this.total = res.total; this.loading = false; }); getVideoInfo().then((res) => { this.allVideoList = res.rows; }); }, handleQuery() { this.queryParams.pageNum = 1; this.getList(); }, resetQuery() { this.resetForm("queryForm"); this.handleQuery(); }, handleAdd() { this.reset(); this.open = true; this.lightPoint = ""; this.title = "新增摄像头"; }, handleUpdate(row) { this.reset(); this.title = "修改"; this.open = true; let id; if (row.id) { id = row.id; this.videoList.forEach((item) => { if (item.id == id) { this.form = JSON.parse(JSON.stringify(item)); this.lightPoint = item.areaName; } }); } else { id = this.ids; this.videoList.forEach((item) => { if (item.id == id[0]) { this.form = JSON.parse(JSON.stringify(item)); this.lightPoint = item.areaName; } }); } }, /** 提交按钮 */ submitForm() { this.$refs["form"].validate((valid) => { if (valid) { if (this.form.id != null) { updateVideo(this.form).then((response) => { this.msgSuccess("修改成功"); this.open = false; this.getList(); }); } else { addVideo(this.form).then((response) => { this.msgSuccess("新增成功"); this.open = false; this.getList(); }); } } }); }, handleDelete(row) { const ids = row.id || this.ids; this.$confirm("是否确认删除该条数据项?", "警告", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning", }) .then(function () { return delVideo(ids); }) .then(() => { this.getList(); this.msgSuccess("删除成功"); }); }, // 多选框选中数据 handleSelectionChange(selection) { this.openVideoData = []; this.openVideoData = selection; this.ids = selection.map((item) => item.id); this.single = selection.length !== 1; this.multiple = !selection.length; }, cancel() { this.open = false; this.reset(); }, reset() { this.form = { ip: null, name: null, username: null, password: null, port: null, coordinate: "", }; this.resetForm("form"); }, }, }; </script>
在点击新增和编辑时会调用地图组件选择坐标,这里与业务相关可忽略。
当点击预览按钮将监控点编号参数传递到预览的窗口页面。
9、预览界面
<template> <el-dialog title="视频监控" :visible.sync="videoOpen" width="800px" append-to-body @close="videoClose" class="video_box" > <!--视频窗口展示--> <div id="playWnd" class="playWnd"></div> </el-dialog> </template> <script> export default { name: "HkVideo", components: {}, props: { videoData: '' }, watch: { videoData() { this.getVideoData(); }, }, data() { return { videoOpen: false, swfHeight: "", swfWidth: "", streamMode: 0, // 主子码流标识:0-主码流,1-子码流 transMode: 1, // 传输协议:0-UDP,1-TCP gpuMode: 0, // 是否启用GPU硬解,0-不启用,1-启用 initParams: {}, previewParams: {}, // 预览参数 oWebControl: null, initCount: 0, pubKey: "", }; }, created() {}, mounted() { this.getVideoData(); $(window).resize(() => { if (this.oWebControl != null) { this.oWebControl.JS_Resize(800, 600); this.setWndCover(); } }); // 监听滚动条scroll事件,使插件窗口跟随浏览器滚动而移动 $(window).scroll(() => { if (this.oWebControl != null) { this.oWebControl.JS_Resize(800, 600); this.setWndCover(); } }); }, destroyed() {}, methods: { getVideoData() { console.log("videoData", this.videoData); this.previewParams = { cameraIndexCode: this.videoData, // 监控点编号 streamMode: 0, // 主子码流标识,0-主码流 1-子码流 transMode: 1, // 传输协议,0-UDP 1-TCP gpuMode: 0, // 是否开启 GPU 硬解,不建议开启,0-不开启 1-开启 }; console.log("this.previewParams", this.previewParams); }, // 创建播放实例 initPlugin() { console.log("init"); // 创建播放容器实例 this.oWebControl = new WebControl({ szPluginContainer: "playWnd", // 指定容器id iServicePortStart: 15900, // 指定起止端口号,建议使用该值 iServicePortEnd: 15909, szClassId: "23BF3B0A-2C56-4D97-9C03-0CB103AA8F11", // 用于IE10使用ActiveX的clsid cbConnectSuccess: () => { // 创建WebControl实例成功 this.oWebControl .JS_StartService("window", { // WebControl实例创建成功后需要启动服务 dllPath: "./VideoPluginConnect.dll", // 值"./VideoPluginConnect.dll"写死 }) .then( () => { // 创建视频实例成功后调用接口创建视频播放窗口 this.oWebControl.JS_CreateWnd("playWnd", 800, 600).then((e) => { //JS_CreateWnd创建视频播放窗口,宽高可设定 console.log("成功创建视频播放窗口"); this.init(); // 创建播放实例成功后初始化 }); }, function () { // 启动插件服务失败 console.log("启动插件服务失败"); } ); }, cbConnectError: () => { // 创建WebControl实例失败 this.oWebControl = null; this.$message({ message: "插件未启动,正在尝试启动,请稍候...", }); WebControl.JS_WakeUp("VideoWebPlugin://"); // 程序未启动时执行error函数,采用wakeup来启动程序 this.initCount++; if (this.initCount < 3) { setTimeout(() => { this.initPlugin(); }, 3000); } else { this.$message.error("插件启动失败,请检查插件是否安装!"); this.myFunction(); } }, cbConnectClose: (bNormalClose) => { // 异常断开:bNormalClose = false // JS_Disconnect正常断开:bNormalClose = true console.log("cbConnectClose"); this.oWebControl = null; }, }); }, //初始化 init() { this.getPubKey(() => { this.initParams = { appkey: "综合安防管理平台提供的appkey", //综合安防管理平台提供的appkey,必填 secret: this.setEncrypt("综合安防管理平台提供的secret"), //综合安防管理平台提供的secret,必填 ip: "综合安防管理平台IP地址", //综合安防管理平台IP地址,必填 playMode: 0, //初始播放模式:0-预览,1-回放 port: 443, //综合安防管理平台端口,若启用HTTPS协议,默认443 snapDir: "D:\\SnapDir", //抓图存储路径 // videoDir: "D:\\VideoDir", //紧急录像或录像剪辑存储路径 layout: "1x1", //playMode指定模式的布局 enableHTTPS: 1, //是否启用HTTPS协议与综合安防管理平台交互,这里总是填1 encryptedFields: "secret", //加密字段,默认加密领域为secret showToolbar: 1, //是否显示工具栏,0-不显示,非0-显示 showSmart: 1, //是否显示智能信息(如配置移动侦测后画面上的线框),0-不显示,非0-显示 buttonIDs: "0,16,256,257,258,259,260,512,513,514,515,516,517,768,769", //自定义工具条按钮 }; this.oWebControl .JS_RequestInterface({ funcName: "init", argument: JSON.stringify(this.initParams), }) .then((oData) => { if (oData.responseMsg.code == 0) { console.log("初始化成功", oData); this.oWebControl.JS_Resize(800, 600); // 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题 this.preview(); } else { this.$message.error(oData.responseMsg.msg); } }); }); }, //预览功能 preview() { console.log("preview"); this.oWebControl .JS_RequestInterface({ funcName: "startPreview", argument: JSON.stringify(this.previewParams), }) .then((e) => { if(e.responseMsg.code == 0) { console.log("预览接口调用成功", e); } }); }, //停止全部预览功能 stopAllPreview() { this.oWebControl.JS_RequestInterface({ funcName: "stopAllPreview", }); }, //关闭视频窗口 closeWindow() { console.log("close"); if (this.oWebControl != null) { this.oWebControl.JS_HideWnd(); // 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题 } }, //获取公钥 getPubKey(callback) { this.oWebControl .JS_RequestInterface({ funcName: "getRSAPubKey", argument: JSON.stringify({ keyLength: 1024, }), }) .then((oData) => { if (oData.responseMsg.data) { console.log("获取公钥成功", oData); this.pubKey = oData.responseMsg.data; callback(); } else { this.$message.error(oData.responseMsg.msg) } }); }, // 设置窗口裁剪,当因滚动条滚动导致窗口需要被遮住的情况下需要JS_CuttingPartWindow部分窗口 setWndCover() { let iWidth = $(window).width(); let iHeight = $(window).height(); let oDivRect = $("#playWnd").get(0).getBoundingClientRect(); let iCoverLeft = oDivRect.left < 0 ? Math.abs(oDivRect.left) : 0; let iCoverTop = oDivRect.top < 0 ? Math.abs(oDivRect.top) : 0; let iCoverRight = oDivRect.right - iWidth > 0 ? Math.round(oDivRect.right - iWidth) : 0; let iCoverBottom = oDivRect.bottom - iHeight > 0 ? Math.round(oDivRect.bottom - iHeight) : 0; iCoverLeft = iCoverLeft > this.swfWidth ? this.swfWidth : iCoverLeft; iCoverTop = iCoverTop > this.swfHeight ? this.swfHeight : iCoverTop; iCoverRight = iCoverRight > this.swfWidth ? this.swfWidth : iCoverRight; iCoverBottom = iCoverBottom > this.swfHeight ? this.swfHeight : iCoverBottom; this.oWebControl.JS_RepairPartWindow( 0, 0, this.swfWidth + 1, this.swfHeight ); // 多1个像素点防止还原后边界缺失一个像素条 if (iCoverLeft != 0) { this.oWebControl.JS_CuttingPartWindow(0, 0, iCoverLeft, this.swfHeight); } if (iCoverTop != 0) { this.oWebControl.JS_CuttingPartWindow( 0, 0, this.swfWidth + 1, iCoverTop ); // 多剪掉一个像素条,防止出现剪掉一部分窗口后出现一个像素条 } if (iCoverRight != 0) { this.oWebControl.JS_CuttingPartWindow( this.swfWidth - iCoverRight, 0, iCoverRight, this.swfHeight ); } if (iCoverBottom != 0) { this.oWebControl.JS_CuttingPartWindow( 0, this.swfHeight - iCoverBottom, this.swfWidth, iCoverBottom ); } }, //RSA加密 setEncrypt(value) { var encrypt = new JSEncrypt(); encrypt.setPublicKey(this.pubKey); return encrypt.encrypt(value); }, myFunction() { var r = confirm("您还未安装过插件,请下载后查看摄像!"); if (r == true) { window.location.href = "/VideoWebPlugin.exe"; } else { } }, // 查看摄像 videoChange() { this.videoOpen = true; this.$nextTick(() => { this.initPlugin(); }); }, // 关闭摄像头弹窗 videoClose() { this.videoOpen = false; this.closeWindow(); }, }, }; </script> <style scoped lang="scss"> .video_box { width: 100%; height: 100%; } .plugin { width: 100%; height: 100%; } .playWnd { width: 800px; height: 600px; margin: 0; } .video_box { ::v-deep .el-dialog__body { padding: 0 !important; } } </style>
注意这里需要将上面获取的appkey、secret等参数填充。
然后这里将提示下载插件的地址改为前端本地地址,防止因内网无法访问外网等原因无法下载插件。
另外需要注意引用js插件的引入,这里直接在public下index.html中引入
<!--海康位置摄像头三个必要的js文件引入--> <scriptsrc="<%= BASE_URL %>static/HK_1.1.0/jquery-1.12.4.min.js"></script> <scriptsrc="<%= BASE_URL %>static/HK_1.1.0/jsencrypt.min.js"></script> <!-- 用于RSA加密 --> <script src="<%= BASE_URL %>static/HK_1.1.0/jsWebControl-1.0.0.min.js"></script> <!-- 用于前端与插件交互 -->
预览效果
标签:function,Vue,SpringBoot,预览,oData,JS,var,iSecure,oWebControl 来源: https://www.cnblogs.com/badaoliumangqizhi/p/16492862.html