package com.ard.utils.hiksdk.service.impl; import com.ard.alarm.camera.domain.ArdCameras; import com.ard.alarm.camera.domain.CameraCmd; import com.ard.utils.hiksdk.common.GlobalVariable; import com.ard.utils.hiksdk.util.hikSdkUtil.HCNetSDK; import com.ard.utils.hiksdk.util.minio.MinioUtils; import com.sun.jna.Native; import com.sun.jna.Platform; import com.sun.jna.ptr.IntByReference; import lombok.extern.slf4j.Slf4j; import java.io.*; import java.nio.ByteBuffer; import java.util.*; import static com.ard.utils.hiksdk.common.GlobalVariable.cameraMap; /** * @ClassName: hikClientServiceImpl * @Description: 海康操作客户端实现类 * @Author: Administrator * @Date: 2023年01月17日 11:25 * @Version: 1.2 **/ @Slf4j(topic = "hikSdk") public class HikClientUtil { private static HCNetSDK hCNetSDK; // 报警回调函数实现 public static HCNetSDK.FMSGCallBack_V31 fMSFCallBack_V31; public static void loadHCNetSDKLib() { try { log.debug("开始加载sdk库文件路径"); if (Platform.isWindows()) { String WIN_PATH = System.getProperty("user.dir") + File.separator + "lib" + File.separator + "HCNetSDK.dll"; log.debug("当前Windows平台的sdk库路径:" + WIN_PATH); hCNetSDK = (HCNetSDK) Native.loadLibrary(WIN_PATH, HCNetSDK.class); } else { log.debug("Linux平台"); String LINUX_PATH = System.getProperty("user.dir") + File.separator + "hiklib" + File.separator + "libhcnetsdk.so"; log.debug("当前Linux平台的sdk库路径:" + LINUX_PATH); hCNetSDK = (HCNetSDK) Native.loadLibrary(LINUX_PATH, HCNetSDK.class); //设置HCNetSDKCom组件库所在路径 //libhcnetsdk.so String strPathCom = "/home/hiklib"; HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH(); System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length()); struComPath.write(); hCNetSDK.NET_DVR_SetSDKInitCfg(2, struComPath.getPointer()); //设置libcrypto.so所在路径 HCNetSDK.BYTE_ARRAY ptrByteArrayCrypto = new HCNetSDK.BYTE_ARRAY(256); String strPathCrypto = "/home/hiklib/libcrypto.so.1.1"; System.arraycopy(strPathCrypto.getBytes(), 0, ptrByteArrayCrypto.byValue, 0, strPathCrypto.length()); ptrByteArrayCrypto.write(); hCNetSDK.NET_DVR_SetSDKInitCfg(3, ptrByteArrayCrypto.getPointer()); //设置libssl.so所在路径 HCNetSDK.BYTE_ARRAY ptrByteArraySsl = new HCNetSDK.BYTE_ARRAY(256); String strPathSsl = "/home/hiklib/libssl.so.1.1"; System.arraycopy(strPathSsl.getBytes(), 0, ptrByteArraySsl.byValue, 0, strPathSsl.length()); ptrByteArraySsl.write(); hCNetSDK.NET_DVR_SetSDKInitCfg(4, ptrByteArraySsl.getPointer()); } } catch (Exception ex) { log.error("加载库文件异常:" + ex.getMessage()); } } /** * @描述 注册登录 只支持同步登陆,且官方不建议直接在此接口下写耗时操作 * @参数 [dvrLogin] * @返回值 java.lang.Integer * @创建人 刘苏义 * @创建时间 2023/1/17 16:12 * @修改人和其它信息 */ public ArdCameras login1(ArdCameras camera) { // 初始化 if (!hCNetSDK.NET_DVR_Init()) { log.error("SDK初始化失败"); } //打印海康sdk日志 if (Platform.isWindows()) { String WIN_PATH = System.getProperty("user.dir") + File.separator + "ardLog" + File.separator + "logs" + File.separator; hCNetSDK.NET_DVR_SetLogToFile(3, WIN_PATH, true); } else { hCNetSDK.NET_DVR_SetLogToFile(3, "/home/ardLog/hiklog", true); } String m_sDeviceIP = camera.getIp(); String m_sUsername = camera.getUsername(); String m_sPassword = camera.getPassword(); short m_sPort = camera.getPort().shortValue(); //设置连接时间与重连时间 hCNetSDK.NET_DVR_SetConnectTime(2000, 1); hCNetSDK.NET_DVR_SetReconnect(100000, true); //设备信息, 输出参数 HCNetSDK.NET_DVR_DEVICEINFO_V30 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30(); int lUserID = hCNetSDK.NET_DVR_Login_V30(m_sDeviceIP, m_sPort, m_sUsername, m_sPassword, m_strDeviceInfo); if (lUserID < 0) { //释放SDK资源 hCNetSDK.NET_DVR_Cleanup(); camera.setLoginId(-1); } if (GlobalVariable.loginMap.containsKey(camera.getId())) { GlobalVariable.loginMap.remove(camera.getId()); } GlobalVariable.loginMap.put(camera.getId(), lUserID); camera.setLoginId(lUserID); camera.setChannel((int) m_strDeviceInfo.byStartChan); return camera; } /** * @描述 注册登录 集成于NET_DVR_Login_V30,支持同步和异步登录 * @参数 [dvrLogin] * @返回值 java.lang.Integer * @创建人 刘苏义 * @创建时间 2023/1/17 16:12 * @修改人和其它信息 */ public static void login(ArdCameras camera) { // 初始化 if (!hCNetSDK.NET_DVR_Init()) { log.error("SDK初始化失败"); } //打印海康sdk日志 if (Platform.isWindows()) { String WIN_PATH = System.getProperty("user.dir") + File.separator + "ardLog" + File.separator + "logs" + File.separator; hCNetSDK.NET_DVR_SetLogToFile(3, WIN_PATH, true); } else { hCNetSDK.NET_DVR_SetLogToFile(3, "/home/ardLog/hiklog", true); } String m_sDeviceIP = camera.getIp(); String m_sUsername = camera.getUsername(); String m_sPassword = camera.getPassword(); short m_sPort = camera.getPort().shortValue(); //设置连接时间与重连时间 hCNetSDK.NET_DVR_SetConnectTime(2000, 1); hCNetSDK.NET_DVR_SetReconnect(100000, true); //设备信息, 输出参数 HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40(); HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO(); // 注册设备-登录参数,包括设备地址、登录用户、密码等 m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN]; System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length()); m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN]; System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length()); m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN]; System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length()); m_strLoginInfo.wPort = m_sPort; m_strLoginInfo.byVerifyMode = 0; m_strLoginInfo.byLoginMode = 0; //是否异步登录:0- 否,1- 是 windowsSDK里是true和false m_strLoginInfo.bUseAsynLogin = true; //异步登录回调 m_strLoginInfo.cbLoginResult = new LoginResultCallBack(camera); m_strLoginInfo.write(); int i = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo); if (i < 0) { int errorCode = hCNetSDK.NET_DVR_GetLastError(); log.info("登录异常:" + errorCode); } } /** * @描述 登录所有相机 * @参数 [] * @返回值 void * @创建人 刘苏义 * @创建时间 2023/2/3 10:10 * @修改人和其它信息 */ public static void loginAll(List ardCameras) { try { log.debug("加载lib完成!"); for (ArdCameras camera : ardCameras) { Thread.sleep(100); login(camera); String ip = camera.getIp(); cameraMap.put(ip,camera); } } catch (Exception ex) { log.error("初始化登录相机异常:" + ex.getMessage()); } } /** * @描述 注销登录 * @参数 [dvrLogin] * @返回值 java.lang.Integer * @创建人 刘苏义 * @创建时间 2023/1/17 16:12 * @修改人和其它信息 */ public static boolean loginOut(String cameraId) { if (!GlobalVariable.loginMap.containsKey(cameraId)) { return false; } Integer userId = GlobalVariable.loginMap.get(cameraId); boolean b = hCNetSDK.NET_DVR_Logout(userId); if (b) { GlobalVariable.loginMap.remove(cameraId); } return b; } /** * 是否在线 * * @param cmd */ public static boolean isOnLine(CameraCmd cmd) { String cameraId = cmd.getCameraId(); if (!GlobalVariable.loginMap.containsKey(cameraId)) { return false; } Integer userId = GlobalVariable.loginMap.get(cameraId); boolean isOnLine = hCNetSDK.NET_DVR_RemoteControl(userId, HCNetSDK.NET_DVR_CHECK_USER_STATUS, null, 0); return isOnLine; } /** * 建立布防上传通道,用于传输数据 * * @param lUserID 唯一标识符 * @param lAlarmHandle 报警处理器 */ public static int setupAlarmChan(int lUserID, int lAlarmHandle) { // 根据设备注册生成的lUserID建立布防的上传通道,即数据的上传通道 if (lUserID == -1) { log.info("请先注册"); return lUserID; } if (lAlarmHandle < 0) { // 设备尚未布防,需要先进行布防 if (fMSFCallBack_V31 == null) { fMSFCallBack_V31 = new FMSGCallBack(); if (!hCNetSDK.NET_DVR_SetDVRMessageCallBack_V50(0, fMSFCallBack_V31, null)) { log.info("设置回调函数失败!错误码==========》" + hCNetSDK.NET_DVR_GetLastError()); } } // 这里需要对设备进行相应的参数设置,不设置或设置错误都会导致设备注册失败 HCNetSDK.NET_DVR_SETUPALARM_PARAM m_strAlarmInfo = new HCNetSDK.NET_DVR_SETUPALARM_PARAM(); m_strAlarmInfo.dwSize = m_strAlarmInfo.size(); // 智能交通布防优先级:0 - 一等级(高),1 - 二等级(中),2 - 三等级(低) m_strAlarmInfo.byLevel = 1; // 智能交通报警信息上传类型:0 - 老报警信息(NET_DVR_PLATE_RESULT), 1 - 新报警信息(NET_ITS_PLATE_RESULT) m_strAlarmInfo.byAlarmInfoType = 1; // 布防类型(仅针对门禁主机、人证设备):0 - 客户端布防(会断网续传),1 - 实时布防(只上传实时数据) m_strAlarmInfo.byDeployType = 1; m_strAlarmInfo.write(); // 布防成功,返回布防成功的数据传输通道号 lAlarmHandle = hCNetSDK.NET_DVR_SetupAlarmChan_V41(lUserID, m_strAlarmInfo); if (lAlarmHandle == -1) { log.error("设备布防失败,错误码==========》" + hCNetSDK.NET_DVR_GetLastError()); log.error("设备布防失败,错误码==========》" + hCNetSDK.NET_DVR_GetLastError()); // 注销 释放sdk资源 logout(lUserID); return lAlarmHandle; } else { log.info("相机布防成功"); return lAlarmHandle; } } return lAlarmHandle; } /** * 注销 * * @param lUserID 设备注册成功唯一标识符 */ public static void logout(int lUserID) { // 注销 hCNetSDK.NET_DVR_Logout(lUserID); // 释放sdk资源 hCNetSDK.NET_DVR_Cleanup(); } /** * 抓图 * * @param cmd 抓图命令 */ public static String picCutCate(CameraCmd cmd) { String cameraId = cmd.getCameraId(); Integer channelNum = cmd.getChannelNum(); if (!GlobalVariable.loginMap.containsKey(cameraId)) { return ""; } Integer userId = GlobalVariable.loginMap.get(cameraId); //图片信息 HCNetSDK.NET_DVR_JPEGPARA jpeg = new HCNetSDK.NET_DVR_JPEGPARA(); //设置图片分辨率 //图片尺寸:0-CIF(352*288/352*240),1-QCIF(176*144/176*120),2-4CIF(704*576/704*480)或D1(720*576/720*486),3-UXGA(1600*1200), // 4-SVGA(800*600),5-HD720P(1280*720),6-VGA(640*480),7-XVGA(1280*960),8-HD900P(1600*900),9-HD1080P(1920*1080),10-2560*1920, // 11-1600*304,12-2048*1536,13-2448*2048,14-2448*1200,15-2448*800,16-XGA(1024*768),17-SXGA(1280*1024),18-WD1(960*576/960*480), // 19-1080I(1920*1080),20-576*576,21-1536*1536,22-1920*1920,23-320*240,24-720*720,25-1024*768,26-1280*1280,27-1600*600, // 28-2048*768,29-160*120,75-336*256,78-384*256,79-384*216,80-320*256,82-320*192,83-512*384,127-480*272,128-512*272, 161-288*320, // 162-144*176,163-480*640,164-240*320,165-120*160,166-576*720,167-720*1280,168-576*960,180-180*240, 181-360*480, 182-540*720, // 183-720*960, 184-960*1280, 185-1080*1440, 500-384*288, 0xff-Auto(使用当前码流分辨率) jpeg.wPicSize = 0; //设置图片质量:0-最好,1-较好,2-一般 jpeg.wPicQuality = 0; IntByReference a = new IntByReference(); //设置图片大小 ByteBuffer jpegBuffer = ByteBuffer.allocate(1024 * 1024); // 抓图到内存,单帧数据捕获并保存成JPEG存放在指定的内存空间中 log.debug("-----------这里开始封装 NET_DVR_CaptureJPEGPicture_NEW---------"); boolean is = hCNetSDK.NET_DVR_CaptureJPEGPicture_NEW(userId, channelNum, jpeg, jpegBuffer, 1024 * 1024, a); log.debug("-----------这里开始图片存入内存----------" + is); if (is) { log.debug("hksdk(抓图)-结果状态值(0表示成功):" + hCNetSDK.NET_DVR_GetLastError()); byte[] array = jpegBuffer.array(); //存储到minio String ContentType = "image/JPEG"; InputStream input = new ByteArrayInputStream(array); String url = ""; try { boolean b = MinioUtils.uploadObject(cmd.getBucketName(), cmd.getObjectName(), input, input.available(), ContentType); if (b) { url = MinioUtils.getBucketObjectUrl(cmd.getBucketName(), cmd.getObjectName()); url = url.indexOf('?') != -1 ? url.substring(0, url.indexOf('?')) : url; log.debug("上传文件成功!" + url); } } catch (IOException ex) { log.error("上传文件异常:" + ex.getMessage()); } return url; } else { int code = hCNetSDK.NET_DVR_GetLastError(); log.debug("抓图失败,请稍后重试" + code); return ""; } } }