海康威视后台监控布防
由于公司业务的需要,前端时间一直在折腾海康摄像头的对接。在这期间踩过许多坑,做一记录分享。
大致的业务场景,主要用到的是海康的 Ai 摄像头与高清摄像头,实现监控布防与实时画面在 web 页面展示预览。
对于 Ai 摄像头内部已经上传了训练好的模型,直接调用海康提供 SDK 接口即可,对于高清摄像则是调用海康 SDK 提供的抓拍功能,保存图片到本地,调用训练好的 Python 模型进行本地图片的算法分析。 实时画面展示只是 Vue 与海康官方提供的 Web3.2 源码进行整合通过 Nginx 代理完成实时画面的同步展示,由于一部分摄像头硬件是不支持 websocket 流传输的,所以前端的页面登录展示并未直接通过摄像头 ip 的方式进行登录,而是配合超脑主机不同的通道号进行登录预览的。
视频布防与抓拍
视频的抓拍与布防可以参考,海康提供的网络设备SDK资料中的 设备网络SDK编程指南(抓拍机)文档
视频布防
可以看到的是(布防)流程是比较简单的
-
初始化 SDK (由于所有的接口都是使用 C++ 语言编写的,所以这里需要将这些开发包初始化为本地的 Java 可以调用执行的程序)
/** * 初始化 hCNetSDK */ public void init(){ /*加载SDK的动态库*/ if (hCNetSDK == null) { if (!CreateSDKInstance()) { System.out.println("Load SDK fail"); } } /*初始化*/ hCNetSDK.NET_DVR_Init(); /*加载日志*/ hCNetSDK.NET_DVR_SetLogToFile(3, "../sdklog", false); //设置报警回调函数 Pointer pUser = null; if (!hCNetSDK.NET_DVR_SetDVRMessageCallBack_V31(fMSFCallBack_V31, pUser)) { System.out.println("设置回调函数失败!"); } else { System.out.println("设置回调函数成功!"); } }
这里的
hCNetSDK.NET_DVR_SetDVRMessageCallBack_V31(fMSFCallBack_V31, pUser)
是报警回调函数,需要进行提前的设置。/** * 动态依赖库加载 * @return */ private static boolean CreateSDKInstance() { if (hCNetSDK == null) { synchronized (HCNetSDK.class) { String strDllPath = ""; try { if (osSelect.isWindows()) { //win系统加载库路径 Resource resource = new ClassPathResource("hikvision/windows/HCNetSDK.dll"); // strDllPath = resource.getFile().getPath(); strDllPath = "D:\\windows\\HCNetSDK.dll"; } else if (osSelect.isLinux()) //Linux系统加载库路径 strDllPath = System.getProperty("user.dir") + "/lib/libhcnetsdk.so"; hCNetSDK = (HCNetSDK) Native.loadLibrary(strDllPath, HCNetSDK.class); } catch (Exception ex) { System.out.println("loadLibrary: " + strDllPath + " Error: " + ex.getMessage()); return false; } } } return true; }
-
登录设备(这里只需根据海康提供的 Dome 调用 login_v40 或者 login 进行登录获取登录成功的用户 Id 号)
/** * * @param ip 设备IP * @param port SDK端口 * @param user 设备用户名 * @param psw 设备密码 */ public static int login_V40(String ip, short port, String user, String psw) { //注册 HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();//设备登录信息 HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();//设备信息 // String m_sDeviceIP = "192.168.0.100";//设备ip地址 m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN]; System.arraycopy(ip.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, ip.length()); // String m_sUsername = "admin";//设备用户名 m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN]; System.arraycopy(user.getBytes(), 0, m_strLoginInfo.sUserName, 0, user.length()); // String m_sPassword = "hzyjy123";//设备密码 m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN]; System.arraycopy(psw.getBytes(), 0, m_strLoginInfo.sPassword, 0, psw.length()); // m_strLoginInfo.wPort = 8085; m_strLoginInfo.wPort = port; m_strLoginInfo.bUseAsynLogin = false; //是否异步登录:0- 否,1- 是 m_strLoginInfo.write(); int lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo); if (lUserID == -1) { log.debug("登录失败,错误码为" + hCNetSDK.NET_DVR_GetLastError()); return lUserID; } log.debug(ip + ":设备登录成功!"); return lUserID; }
-
报警布放(这里的 lUserID 就是之前登录成功后返回的用户 ID,这个 ID 在登录成功的情况下是唯一的)
/** * 报警布防接口 * * @param lUserID */ public static int setAlarm(int lUserID) { //报警布防参数设置 HCNetSDK.NET_DVR_SETUPALARM_PARAM m_strAlarmInfo = new HCNetSDK.NET_DVR_SETUPALARM_PARAM(); m_strAlarmInfo.dwSize = m_strAlarmInfo.size(); m_strAlarmInfo.byLevel = 0; //布防等级 m_strAlarmInfo.byAlarmInfoType = 1; // 智能交通报警信息上传类型:0- 老报警信息(NET_DVR_PLATE_RESULT),1- 新报警信息(NET_ITS_PLATE_RESULT) m_strAlarmInfo.byDeployType = 0; //布防类型:0-客户端布防,1-实时布防 m_strAlarmInfo.write(); int lAlarmHandle = hCNetSDK.NET_DVR_SetupAlarmChan_V41(lUserID, m_strAlarmInfo); System.out.println("lAlarmHandle: " + lAlarmHandle); if (lAlarmHandle == -1) { logout(lUserID); log.debug("布防失败,错误码为" + hCNetSDK.NET_DVR_GetLastError()); return lAlarmHandle; } log.debug("布防成功"); return lAlarmHandle; }