Browse Source

摄像头基本参数改为ipcIp

ZhangWenTao 2 years ago
parent
commit
726bdb79ef

+ 197 - 0
src/main/java/com/persagy/cameractl/cache/IPCWithNVRCache.java

@@ -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;
+
+    }
+
+}

+ 54 - 0
src/main/java/com/persagy/cameractl/conf/NVRConfigurationProperties.java

@@ -0,0 +1,54 @@
+package com.persagy.cameractl.conf;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.List;
+
+/**
+ * @author : ZhangWenTao
+ * @version : 1.0
+ * @since : 2022/6/27 15:01
+ */
+@Data
+@Configuration
+@ConfigurationProperties(prefix = "nvr-conf")
+public class NVRConfigurationProperties {
+
+    /**
+     * @see NVRItem
+     */
+    private List<NVRItem> items;
+
+    @Data
+    public static class NVRItem {
+
+        /**
+         * 名称
+         */
+        private String name;
+
+        /**
+         * IP
+         */
+        private String ip;
+
+        /**
+         * 端口
+         */
+        private int port;
+
+        /**
+         * 账户名称
+         */
+        private String username;
+
+        /**
+         * 密码
+         */
+        private String password;
+
+    }
+
+}

+ 5 - 2
src/main/java/com/persagy/cameractl/controller/HelloController.java

@@ -16,6 +16,7 @@ import java.util.Set;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.CrossOrigin;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
@@ -44,6 +45,9 @@ import lombok.extern.slf4j.Slf4j;
 @RestController
 public class HelloController {
 
+	@Autowired
+	private PtzMain ptzMain;
+
 	@RequestMapping(value = "/hello/{name}", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
 	public @ResponseBody String helloName(@PathVariable("name") String name) {
 
@@ -63,8 +67,7 @@ public class HelloController {
 	 */
 	@RequestMapping(value = "/sdk/{opertype}", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
 	public String ptzOperation(@PathVariable("opertype") String operType, @RequestBody Camera _camera) {
-		PtzMain pcControlMain = new PtzMain();
-		ResultClass result = pcControlMain.ptzOper(_camera, operType);
+		ResultClass result = ptzMain.ptzOper(_camera, operType);
 		switch (String.valueOf(result.name)) {
 			// 调用成功
 			case "true":

+ 7 - 0
src/main/java/com/persagy/cameractl/init/SystemInit.java

@@ -3,6 +3,7 @@ package com.persagy.cameractl.init;
 import java.util.HashMap;
 import java.util.Map;
 
+import com.persagy.cameractl.cache.IPCWithNVRCache;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.ApplicationArguments;
 import org.springframework.boot.ApplicationRunner;
@@ -30,6 +31,9 @@ public class SystemInit implements ApplicationRunner {
 	@Autowired
 	private CameraConfig cameraConfig;
 
+	@Autowired
+	private IPCWithNVRCache ipcWithNVRCache;
+
 	@Override
 	public void run(ApplicationArguments args) throws Exception {
 		AllStaticConfig.zhaoshangMesHost = cameraConfig.getZhaoshangMesHost();
@@ -48,6 +52,9 @@ public class SystemInit implements ApplicationRunner {
 		this.initSdk();
 		this.setCustomCallBak();
 
+		// 加载IPC与NVR关系缓存
+		ipcWithNVRCache.reload();
+
 		log.info("init project success ...");
 
 		// 启动定时清除文件的定时器

+ 54 - 23
src/main/java/com/persagy/cameractl/service/PtzMain.java

@@ -1,30 +1,57 @@
 package com.persagy.cameractl.service;
 
+import com.persagy.cameractl.cache.IPCWithNVRCache;
+import com.persagy.cameractl.conf.NVRConfigurationProperties;
 import com.persagy.cameractl.service.windows.ZhaosMainWindows;
 import com.persagy.cameractl.utils.Camera;
 import com.persagy.cameractl.utils.OtherTools;
 import com.persagy.cameractl.utils.ResultClass;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Optional;
 
 /**
  * 摄像头相关调用的入口
  */
+@Component
 public class PtzMain {
 
-	/**
-	 * 摄像头操作接口,包括:摄像头控制、回放
-	 */
-	public ResultClass ptzOper(Camera _camera, String operType) {
-		ZhaosMainWindows zhaosMainWindows = new ZhaosMainWindows(_camera);
-		switch (operType) {
-		case "control":
-			return zhaosMainWindows.controlMain();
-		case "playback":
-			return zhaosMainWindows.playBackMain();
-		case "searchlog":
-			return zhaosMainWindows.searchLogMain();
-		default:
-			return OtherTools.executeErr("暂不支持");
-		}
+    @Autowired
+    private IPCWithNVRCache ipcWithNVRCache;
+
+    /**
+     * 摄像头操作接口,包括:摄像头控制、回放
+     */
+    public ResultClass ptzOper(Camera _camera, String operType) {
+
+        Optional<IPCWithNVRCache.IPCInfo> optional = ipcWithNVRCache.get(_camera.ipcIp);
+
+        if (!optional.isPresent()) {
+            return OtherTools.executeErr("未找到对应的ipc");
+        }
+
+        IPCWithNVRCache.IPCInfo ipcInfo = optional.get();
+        NVRConfigurationProperties.NVRItem nvr = ipcInfo.getNvr();
+        _camera.cameraIp = nvr.getIp();
+        _camera.cameraPort = nvr.getPort();
+        _camera.channel = ipcInfo.getChannel();
+
+        _camera.userName = nvr.getUsername();
+        _camera.password = nvr.getPassword();
+
+        ZhaosMainWindows zhaosMainWindows = new ZhaosMainWindows(_camera);
+
+        switch (operType) {
+            case "control":
+                return zhaosMainWindows.controlMain();
+            case "playback":
+                return zhaosMainWindows.playBackMain();
+            case "searchlog":
+                return zhaosMainWindows.searchLogMain();
+            default:
+                return OtherTools.executeErr("暂不支持");
+        }
 		
 		/*OperatingSystem systemName = OtherTools.getSystemName();
 		switch (systemName) {
@@ -35,13 +62,17 @@ public class PtzMain {
 		default:
 			return OtherTools.executeErr("暂不支持");
 		}*/
-	};
-
-	/**
-	 * 摄像头实时播放入口
-	 */
-	public ResultClass realPlay(Camera _camera) {
-		return OtherTools.executeErr("暂不支持");
-	};
+    }
+
+    ;
+
+    /**
+     * 摄像头实时播放入口
+     */
+    public ResultClass realPlay(Camera _camera) {
+        return OtherTools.executeErr("暂不支持");
+    }
+
+    ;
 
 }

+ 2 - 2
src/main/java/com/persagy/cameractl/service/windows/ZhaosMainWindows.java

@@ -146,7 +146,7 @@ public class ZhaosMainWindows {
 		try {
 			int controlCode = getControlCode();
 			Map<String, Integer> reqPtzControlMap = new HashMap<String, Integer>();
-			reqPtzControlMap.put("chid", _camera.channel - 1);
+			reqPtzControlMap.put("chid", _camera.channel);
 			reqPtzControlMap.put("ptz_cmd", controlCode);
 			reqPtzControlMap.put("value", _camera.speed);
 
@@ -187,7 +187,7 @@ public class ZhaosMainWindows {
 			long endTimeSeconds = new DateUtil(_camera.endDateStr).getSecondsStart1970UTC8();
 
 			Map<String, Object> playbackStreamTimeMap = new HashMap<>();
-			playbackStreamTimeMap.put("chid", _camera.channel - 1);
+			playbackStreamTimeMap.put("chid", _camera.channel);
 			playbackStreamTimeMap.put("stream_type", _camera.streamType);
 			playbackStreamTimeMap.put("start_time", startTimeSeconds);
 			playbackStreamTimeMap.put("end_time", endTimeSeconds);

+ 5 - 0
src/main/java/com/persagy/cameractl/utils/Camera.java

@@ -11,6 +11,11 @@ import javax.validation.constraints.Min;
  * 摄像头对象
  * */
 public class Camera {
+
+	/**
+	 * 摄像头IP
+	 */
+	public String ipcIp;
 	
 	// 通道号 1~32表示模拟通道,9000系列混合型DVR和NVR等设备的IP通道从33开始(即程序用的通道号为33+通道号-1)。回放、实时播放、控制使用
 	@Min(1)

+ 80 - 0
src/main/java/com/persagy/nvr/ReqSetServerUriInfo.java

@@ -0,0 +1,80 @@
+package com.persagy.nvr;
+
+import com.alibaba.fastjson.PropertyNamingStrategy;
+import com.alibaba.fastjson.annotation.JSONField;
+import com.alibaba.fastjson.annotation.JSONType;
+import com.alibaba.fastjson.parser.DefaultJSONParser;
+import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
+import lombok.Data;
+import lombok.SneakyThrows;
+import sun.misc.BASE64Decoder;
+
+import java.lang.reflect.Type;
+
+/**
+ * IPC配置列表 NvrServerUriList
+ *
+ * @author : ZhangWenTao
+ * @version : 1.0
+ * @since : 2022/6/27 11:00
+ */
+@Data
+@JSONType(naming = PropertyNamingStrategy.SnakeCase)
+public class ReqSetServerUriInfo {
+
+    /**
+     * 当前添加的IPC在NVR上的通道ID
+     */
+    private int chid;
+
+    /**
+     * 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;
+
+    /**
+     * 设备名称
+     */
+    @JSONField(deserializeUsing = DeviceNameDeserializer.class)
+    private String deviceName;
+
+    /**
+     * 192.168.0.123
+     */
+    private String ip;
+
+    /**
+     * port
+     */
+    private int port;
+
+    /**
+     * GB28181协议类型: 对应的国标id
+     */
+    private String sipGbId;
+
+    /**
+     * 在线状态 1-是 0-否
+     */
+    private String onlineStatus;
+
+    public static class DeviceNameDeserializer implements ObjectDeserializer {
+
+        @Override
+        @SneakyThrows
+        public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
+            return (T) new String(new BASE64Decoder().decodeBuffer(String.valueOf(parser.parseKey())));
+        }
+
+        @Override
+        public int getFastMatchToken() {
+            return 0;
+        }
+    }
+
+}

+ 20 - 0
src/main/java/com/persagy/nvr/ReqSetServerUriInfoResp.java

@@ -0,0 +1,20 @@
+package com.persagy.nvr;
+
+import com.alibaba.fastjson.PropertyNamingStrategy;
+import com.alibaba.fastjson.annotation.JSONType;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author : ZhangWenTao
+ * @version : 1.0
+ * @since : 2022/6/27 11:26
+ */
+@Data
+@JSONType(naming = PropertyNamingStrategy.SnakeCase)
+public class ReqSetServerUriInfoResp {
+
+    private List<ReqSetServerUriInfo> ipcList;
+
+}

File diff suppressed because it is too large
+ 1 - 5
src/main/resources/application.yml