|
@@ -0,0 +1,197 @@
|
|
|
+package com.persagy.cameractl.cache;
|
|
|
+
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.persagy.cameractl.conf.AllStaticConfig;
|
|
|
+import com.persagy.cameractl.conf.NVRConfigurationProperties;
|
|
|
+import com.persagy.cameractl.utils.JsonTools;
|
|
|
+import com.persagy.nvr.ReqSetServerUriInfo;
|
|
|
+import com.persagy.nvr.ReqSetServerUriInfoResp;
|
|
|
+import com.sun.jna.platform.win32.WinDef;
|
|
|
+import lombok.Data;
|
|
|
+import lombok.SneakyThrows;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+import sun.misc.BASE64Encoder;
|
|
|
+
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author : ZhangWenTao
|
|
|
+ * @version : 1.0
|
|
|
+ * @since : 2022/6/27 15:08
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Component
|
|
|
+public class IPCWithNVRCache {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private NVRConfigurationProperties nvrConfigurationProperties;
|
|
|
+
|
|
|
+ private volatile Map<String, IPCInfo> cache = Collections.emptyMap();
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据IPC IP获取IPC信息
|
|
|
+ *
|
|
|
+ * @param ipcIp IPC IP
|
|
|
+ * @return IPCInfo
|
|
|
+ */
|
|
|
+ public Optional<IPCInfo> get(String ipcIp) {
|
|
|
+ return Optional.ofNullable(cache.get(ipcIp));
|
|
|
+ }
|
|
|
+
|
|
|
+ @SneakyThrows
|
|
|
+ public synchronized void reload() {
|
|
|
+ if (AllStaticConfig.vskClient == null) {
|
|
|
+ throw new RuntimeException("SdkJsonDll未初始化成功,请重启应用程序");
|
|
|
+ }
|
|
|
+
|
|
|
+ final Map<String, IPCInfo> cache = new HashMap<>();
|
|
|
+
|
|
|
+ for (NVRConfigurationProperties.NVRItem nvrItem : nvrConfigurationProperties.getItems()) {
|
|
|
+ // 登录
|
|
|
+ WinDef.DWORD loginHandler = login(nvrItem);
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 读取IPC信息, 构建缓存
|
|
|
+ for (ReqSetServerUriInfo reqSetServerUriInfo : loadNvrIpcInfo(loginHandler, nvrItem)) {
|
|
|
+ cache.put(reqSetServerUriInfo.getIp(), new IPCInfo(reqSetServerUriInfo, nvrItem));
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("reload nvr: {} ipc info", nvrItem.getIp());
|
|
|
+ } finally {
|
|
|
+ //登出
|
|
|
+ AllStaticConfig.vskClient.JsonSdk_Logout(loginHandler);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ IPCWithNVRCache.this.cache = cache;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<ReqSetServerUriInfo> loadNvrIpcInfo(WinDef.DWORD loginHandler,
|
|
|
+ NVRConfigurationProperties.NVRItem nvrItem) throws Exception {
|
|
|
+ int pIPCServerListSize = 4 * 1024 * 1024;
|
|
|
+ byte[] pIPCServerList = new byte[pIPCServerListSize];
|
|
|
+ WinDef.UINTByReference nRealSizeRef = new WinDef.UINTByReference(
|
|
|
+ new WinDef.UINT(pIPCServerListSize));
|
|
|
+
|
|
|
+ int resultCode = AllStaticConfig.vskClient.JsonSdk_ListIPC(
|
|
|
+ loginHandler, pIPCServerList, nRealSizeRef);
|
|
|
+
|
|
|
+ if (nRealSizeRef.getValue().intValue() >= pIPCServerListSize) {
|
|
|
+ WinDef.UINT nRealSize = nRealSizeRef.getValue();
|
|
|
+ nRealSize.setValue(nRealSize.intValue() + 100);
|
|
|
+ pIPCServerList = new byte[nRealSize.intValue()];
|
|
|
+
|
|
|
+ resultCode = AllStaticConfig.vskClient.JsonSdk_ListIPC(
|
|
|
+ loginHandler, pIPCServerList, nRealSizeRef);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (resultCode != 0) {
|
|
|
+ throw new Exception("JsonSdk_ListIPC fail:" + resultCode + " nvr:" + JsonTools.obj2Str(nvrItem));
|
|
|
+ }
|
|
|
+
|
|
|
+ ReqSetServerUriInfoResp resp = JSON.parseObject(
|
|
|
+ new String(pIPCServerList, 0, nRealSizeRef.getValue().intValue()),
|
|
|
+ ReqSetServerUriInfoResp.class);
|
|
|
+
|
|
|
+ return ObjectUtil.defaultIfNull(resp.getIpcList(), Collections.emptyList());
|
|
|
+ }
|
|
|
+
|
|
|
+ private WinDef.DWORD login(NVRConfigurationProperties.NVRItem nvrItem) throws Exception {
|
|
|
+ Map<String, String> userinfoMap = new HashMap<>();
|
|
|
+ String userNameBase64 = new BASE64Encoder().encode(nvrItem.getUsername().getBytes());
|
|
|
+ String passwordBase64 = new BASE64Encoder().encode(nvrItem.getPassword().getBytes());
|
|
|
+ userinfoMap.put("user_name", userNameBase64);
|
|
|
+ userinfoMap.put("password", passwordBase64);
|
|
|
+
|
|
|
+ Map<String, Object> loginInfoMap = new HashMap<>();
|
|
|
+ loginInfoMap.put("user_info", userinfoMap);
|
|
|
+ loginInfoMap.put("strNvrIp", nvrItem.getIp());
|
|
|
+ loginInfoMap.put("nNvrPort", nvrItem.getPort());
|
|
|
+
|
|
|
+ String pReqClientLoginStr = JsonTools.obj2Str(loginInfoMap);
|
|
|
+
|
|
|
+ WinDef.DWORD pnLoginDword = new WinDef.DWORD(0);
|
|
|
+ WinDef.DWORDByReference pnLoginID = new WinDef.DWORDByReference(pnLoginDword);
|
|
|
+ int logId = AllStaticConfig.vskClient.JsonSdk_Login(
|
|
|
+ pReqClientLoginStr,
|
|
|
+ pnLoginID,
|
|
|
+ null,
|
|
|
+ null,
|
|
|
+ null,
|
|
|
+ null);
|
|
|
+
|
|
|
+ if (logId != 0) {
|
|
|
+ throw new Exception("JsonSdk_Login fail:" + logId + " nvr:" + JsonTools.obj2Str(nvrItem));
|
|
|
+ }
|
|
|
+
|
|
|
+ return pnLoginID.getValue();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Data
|
|
|
+ public static class IPCInfo {
|
|
|
+
|
|
|
+ public IPCInfo(ReqSetServerUriInfo reqSetServerUriInfo, NVRConfigurationProperties.NVRItem nvr) {
|
|
|
+ this.ip = reqSetServerUriInfo.getIp();
|
|
|
+ this.port = reqSetServerUriInfo.getPort();
|
|
|
+ this.channel = reqSetServerUriInfo.getChid();
|
|
|
+ this.deviceType = reqSetServerUriInfo.getDeviceType();
|
|
|
+ this.protocolType = reqSetServerUriInfo.getProtocolType();
|
|
|
+ this.deviceName = reqSetServerUriInfo.getDeviceName();
|
|
|
+ this.sipGbId = reqSetServerUriInfo.getSipGbId();
|
|
|
+ this.onlineStatus = reqSetServerUriInfo.getOnlineStatus();
|
|
|
+ this.nvr = nvr;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 192.168.0.123
|
|
|
+ */
|
|
|
+ private String ip;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * port
|
|
|
+ */
|
|
|
+ private int port;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 当前添加的IPC在NVR上的通道ID
|
|
|
+ */
|
|
|
+ private int channel;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * what 's type of device that video stream get from. 1 for IPC stream 2 for NVR stream
|
|
|
+ */
|
|
|
+ private int deviceType;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 协议类型, ONVIF为0
|
|
|
+ */
|
|
|
+ private int protocolType;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设备名称
|
|
|
+ */
|
|
|
+ private String deviceName;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * GB28181协议类型: 对应的国标id
|
|
|
+ */
|
|
|
+ private String sipGbId;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 在线状态 1-是 0-否
|
|
|
+ */
|
|
|
+ private String onlineStatus;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * NVR
|
|
|
+ */
|
|
|
+ private NVRConfigurationProperties.NVRItem nvr;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+}
|