1.后端
1.1 导入依赖
<dependency> <groupId>com.hikvision.ga</groupId> <artifactId>artemis-http-client</artifactId> <version>1.1.3</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.51</version> </dependency>
1.2 代码实战
新建ArtemisPostTest类,代码如下,设置认证信息,设置ArtemisConfig的host,appKey(AK),appSecret(SK)。设置接口URL。.设置接口入参。接口调用,调用doPostStringArtemis方法(该方法内部实现了登入认证逻辑),传入接口URL,接口入参,数据提交类型等信息,完成接口调用。
public class ArtemisPostTest { static { ArtemisConfig.host = "";// 代理API网关nginx服务器ip端口 ArtemisConfig.appKey = "";// 秘钥appkey ArtemisConfig.appSecret = "";// 秘钥appSecret } /** * 能力开放平台的网站路径 * TODO 路径不用修改,就是/artemis */ private static final String ARTEMIS_PATH = "/artemis"; public static String path=""; public static JSONObject jsonBody=new JSONObject(); /** * 调用POST请求类型(application/json)接口,这里以入侵报警事件日志为例 * https://open.hikvision.com/docs/918519baf9904844a2b608e558b21bb6#e6798840 * * @return */ public static String callPostStringApi(){ /** * http://10.33.47.50/artemis/api/scpms/v1/eventLogs/searches * 根据API文档可以看出来,这是一个POST请求的Rest接口,而且传入的参数值为一个json * ArtemisHttpUtil工具类提供了doPostStringArtemis这个函数,一共六个参数在文档里写明其中的意思,因为接口是https, * 所以第一个参数path是一个hashmap类型,请put一个key-value,query为传入的参数,body为传入的json数据 * 传入的contentType为application/json,accept不指定为null * header没有额外参数可不传,指定为null * */ final String getCamsApi = ARTEMIS_PATH +ArtemisPostTest.path; Map<String, String> path = new HashMap<String, String>(2) { { put("https://", getCamsApi);//根据现场环境部署确认是http还是https } }; String body = jsonBody.toJSONString(); String result = ArtemisHttpUtil.doPostStringArtemis(path,body,null,null,"application/json",null);// post请求application/json类型参数 return result; } }
新建实体类Camera代码如下:
@Data @AllArgsConstructor @NoArgsConstructor @Accessors(chain = true) public class Camera { String cameraIndexCode; String camereName; String url; }
在Controller中进行调用,代码如下:
首先根据分页获取监控点列表,这里获取的是第三页,每一页为六个监控点。
查询监控点列表v2
接口说明
根据条件查询目录下有权限的监控点列表
接口版本
v2
接口地址
/api/resource/v2/camera/search
请求方法
POST
数据提交方式
application/json
然后根据监控点唯一的标识获取预览url
接口说明
1.平台正常运行;平台已经添加过设备和监控点信息。
2.平台需要安装mgc取流服务。
3.三方平台通过openAPI获取到监控点数据,依据自身业务开发监控点导航界面。
4.调用本接口获取预览取流URL,协议类型包括:hik、rtsp、rtmp、hls。
5.通过开放平台的开发包进行实时预览或者使用标准的GUI播放工具进行实时预览。
6.为保证数据的安全性,取流URL设有有效时间,有效时间为5分钟。
接口版本
v2
接口地址
/api/video/v2/cameras/previewURLs
请求方法
POST
数据提交方式
application/json
最后就是进行属性的赋值,赋值给建立的Camera 实体类。
@GetMapping("/test") public List<Camera> test(){ ArtemisPostTest.path="/api/resource/v1/cameras"; ArtemisPostTest.jsonBody.clear(); ArtemisPostTest.jsonBody.put("pageNo", 3); ArtemisPostTest.jsonBody.put("pageSize", 6); String StringeResult = ArtemisPostTest.callPostStringApi(); JSONObject result = (JSONObject) JSONObject.parse(StringeResult); String data = result.get("data").toString(); JSONObject resultdata = (JSONObject) JSONObject.parse(data); JSONArray list = resultdata.getJSONArray("list"); // System.out.println("StringeResult结果示例: "+JSONObject.toJSON(StringeResult)); // callPostImgStringApi(); ArtemisPostTest.path="/api/video/v2/cameras/previewURLs"; List<Camera> cameraList=new ArrayList<>(); for (Object i : list) { Camera camera=new Camera(); JSONObject jsonObject = (JSONObject) JSONObject.parse(i.toString()); String cameraIndexCode = jsonObject.get("cameraIndexCode").toString(); String cameraName = jsonObject.get("cameraName").toString(); ArtemisPostTest.jsonBody.clear(); ArtemisPostTest.jsonBody.put("cameraIndexCode",cameraIndexCode); ArtemisPostTest.jsonBody.put("protocol","rtsp"); String m = ArtemisPostTest.callPostStringApi(); JSONObject jsonObject1 = (JSONObject) JSONObject.parse(m); JSONObject data1 = (JSONObject) jsonObject1.get("data"); String url = data1.get("url").toString(); camera.setCameraIndexCode(cameraIndexCode).setCamereName(cameraName).setUrl(url); cameraList.add(camera); } return cameraList; }
2.前端
2.1 首先安装海康的web插件,前端vue3代码如下:
<template> <div style="display: flex;flex-direction: row;flex-wrap: wrap"> <div v-for="item in state.list"> <el-button @click="go(item.cameraIndexCode)">预览{{item.camereName}}</el-button> </div> </div> <div class="main" ref="playWndBox"> <div id="playWnd" class="playWnd" :style="{ height: playWndHeight + 'px', width: playWndWidth + 'px', }" ></div> </div> </template> <script setup> import { ref, onMounted, onBeforeUnmount, getCurrentInstance, nextTick,reactive } from 'vue' import axios from "../utils/axios.js" const playWndBox = ref(null) let playWndHeight = ref('') let playWndWidth = ref('') let pubKey = ref('') let oWebControl = ref(null) let objData = ref({ appkey: "", //海康提供的appkey ip: "", //海康提供的ip secret: "", //海康提供的secret port: 443, playMode: 0, // 0 预览 1回放 layout: "1x1", //页面展示的模块数【16】 }) const go=(data)=>{ previewVideo(data) } const state=reactive({ list:[] }) const load=()=>{ axios.get("/test").then(res=>{ state.list=res console.log(res) }) } load() onMounted(() => { // 获取页面的实例对象 const pageInstance = getCurrentInstance(); // 获取dom节点对象 const tagDomObj = pageInstance.refs.playWndBox; playWndHeight.value = tagDomObj.clientHeight; playWndWidth.value = tagDomObj.clientWidth; // 监听scroll事件,使插件窗口尺寸跟随DIV窗口变化 window.addEventListener("scroll", () => { console.log(5); // return if (oWebControl.value != null) { oWebControl.JS_Resize( tagDomObj.clientWidth, tagDomObj.clientHeight ); this.setWndCover(); } }); // 监听resize事件,使插件窗口尺寸跟随DIV窗口变化 window.addEventListener("resize", (e) => { console.log(0); if (oWebControl.value != null) { oWebControl.JS_Resize( tagDomObj.clientWidth, tagDomObj.clientHeight ); this.setWndCover(); } }); // 初始化播放器插件 nextTick(() => { initPlugin(); }) }) onBeforeUnmount(() => { if (oWebControl.value != null) { // 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题 oWebControl.JS_HideWnd(); // 销毁当前播放的视频 oWebControl.JS_RequestInterface({ funcName: "destroyWnd" }); // 断开与插件服务连接 oWebControl.JS_Disconnect(); } }) const initPlugin = () => { oWebControl = new WebControl({ szPluginContainer: "playWnd", // 指定容器id iServicePortStart: 15900, // 指定起止端口号,建议使用该值 iServicePortEnd: 15900, szClassId: "23BF3B0A-2C56-4D97-9C03-0CB103AA8F11", // 用于IE10使用ActiveX的clsid cbConnectSuccess: () => { // 创建WebControl实例成功 oWebControl .JS_StartService("window", { // WebControl实例创建成功后需要启动服务 // 值"./VideoPluginConnect.dll"写死 dllPath: "./VideoPluginConnect.dll", }) .then( function () { // 设置消息回调 oWebControl.JS_SetWindowControlCallback({ // cbIntegrationCallBack: cbIntegrationCallBack, }); //JS_CreateWnd创建视频播放窗口,宽高可设定 oWebControl .JS_CreateWnd("playWnd", 1152, 581, { bEmbed: true })//这一部分很重要,两个参数为你盒子的宽高,这样是写死是防止组件加载之前出现白屏;bEmbed: true 防止窗口闪烁 .then(function () { // 创建播放实例成功后初始化 init(); }); }, function () { // 启动插件服务失败 } ); }, // 创建WebControl实例失败 cbConnectError: function () { // 这里写创建WebControl实例失败时的处理步骤,下面的代码仅做参看,具体实现步骤根据个人需求进行编写!!!!!!!! // console.log(0); // oWebControl.value = null; // // 程序未启动时执行error函数,采用wakeup来启动程序 // window.WebControl.JS_WakeUp("VideoWebPlugin://"); // initCount++; // if (initCount < 3) { // setTimeout(function () { // initPlugin(); // }, 3000); // } else { // setTimeout(function () { // setTimeout(function () { // $router.push('/home/PlugDown') // }, 4000) // }, 4000) // } }, cbConnectClose: () => { // 异常断开:bNormalClose = false // JS_Disconnect正常断开:bNormalClose = true // console.log("cbConnectClose"); oWebControl.value = null; }, }); // oWebControl.JS_CuttingPartWindow(500, 500, 500, 500); } // 初始化 const init = (callback) => { getPubKey(() => { let appkey = objData.value.appkey; //综合安防管理平台提供的appkey,必填 let secret = setEncrypt(objData.value.secret); //综合安防管理平台提供的secret,必填 let ip = objData.value.ip; //综合安防管理平台IP地址,必填 let playMode = objData.value.playMode; //初始播放模式:0-预览,1-回放 let port = objData.value.port; //综合安防管理平台端口,若启用HTTPS协议,默认443 let snapDir = "D:\\SnapDir"; //抓图存储路径 let videoDir = "D:\\VideoDir"; //紧急录像或录像剪辑存储路径 let layout = objData.value.layout; //playMode指定模式的布局 let enableHTTPS = 1; //是否启用HTTPS协议与综合安防管理平台交互,这里总是填1 let encryptedFields = "secret"; //加密字段,默认加密领域为secret let showToolbar = 1; //是否显示工具栏,0-不显示,非0-显示 let showSmart = 0; //是否显示移动框线框,0-不显示,非0-显示 let buttonIDs = "0,16,256,257,258,259,260,512,513,514,515,516,517,768,769"; //自定义工具条按钮 // var toolBarButtonIDs = "2049,2304" // 工具栏上自定义按钮 oWebControl .JS_RequestInterface({ funcName: "init", argument: JSON.stringify({ appkey: appkey, //API网关提供的appkey secret: secret, //API网关提供的secret ip: ip, //API网关IP地址 playMode: playMode, //播放模式(决定显示预览还是回放界面) port: port, //端口 snapDir: snapDir, //抓图存储路径 videoDir: videoDir, //紧急录像或录像剪辑存储路径 layout: layout, //布局 enableHTTPS: enableHTTPS, //是否启用HTTPS协议 encryptedFields: encryptedFields, //加密字段 showToolbar: showToolbar, //是否显示工具栏 showSmart: showSmart, //是否显示智能信息 buttonIDs, //自定义工具条按钮 }), }) .then(function (oData) { oWebControl.JS_Resize(playWndWidth.value, playWndHeight.value); // 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题 if (callback) { callback(); } // 隐藏 // oWebControl.JS_HideWnd() }); }); } // RSA 加密 let setEncrypt = (value) => { let encrypt = new window.JSEncrypt(); encrypt.setPublicKey(pubKey); return encrypt.encrypt(value); } // 获取公钥 const getPubKey = (callback) => { oWebControl .JS_RequestInterface({ funcName: "getRSAPubKey", argument: JSON.stringify({ keyLength: 1024, }), }) .then(function (oData) { if (oData.responseMsg.data) { pubKey = oData.responseMsg.data; callback(); } }); } // 调用这个函数可进行视频播放 // 视频预览功能 const previewVideo = (data) => { let cameraIndexCode = data; // 获取输入的监控点编号值,必填 let streamMode = 0; // 主子码流标识:0-主码流,1-子码流 let transMode = 1; // 传输协议:0-UDP,1-TCP let gpuMode = 0; // 是否启用GPU硬解,0-不启用,1-启用 let wndId = -1; // 播放窗口序号(在2x2以上布局下可指定播放窗口) oWebControl.JS_RequestInterface({ funcName: "startPreview", argument: JSON.stringify({ cameraIndexCode: cameraIndexCode, // 监控点编号 streamMode: streamMode, // 主子码流标识 transMode: transMode, // 传输协议 gpuMode: gpuMode, // 是否开启GPU硬解 wndId: wndId, // 可指定播放窗口 }), }) .then(function () { oWebControl.JS_SetWindowControlCallback({ }); }); } </script> <style scoped> .main { position: fixed; top: 50%; left: 20%; transform: translateY(-50%); width: 60vw; height: 60vh; margin: auto; background-color: #ccc; } </style>