unknown vor 3 Jahren
Commit
58f824f438
100 geänderte Dateien mit 11678 neuen und 0 gelöschten Zeilen
  1. BIN
      config/lib/DecoderLib.dll
  2. BIN
      config/lib/G711SoundPlay.dll
  3. BIN
      config/lib/libfaac.dll
  4. BIN
      config/lib/libmp4v2.dll
  5. BIN
      config/lib/sdkJson.dll
  6. BIN
      config/lib/sdkJson.lib
  7. BIN
      config/lib/sdkJson.pdb
  8. BIN
      config/lib/sdkJson_new.dll
  9. BIN
      config/lib/sdkJson_old.dll
  10. BIN
      config/nvr9000/windows/DecoderLib.dll
  11. BIN
      config/nvr9000/windows/DecoderLib.lib
  12. BIN
      config/nvr9000/windows/DecoderLib.pdb
  13. BIN
      config/nvr9000/windows/G711SoundPlay.dll
  14. BIN
      config/nvr9000/windows/NSDEVNET.dll
  15. BIN
      config/nvr9000/windows/NSDEVNET.lib
  16. BIN
      config/nvr9000/windows/NSDEVNET.pdb
  17. BIN
      config/nvr9000/windows/nvrdemo
  18. BIN
      config/nvr9000/windows/opencv_core341.dll
  19. BIN
      config/nvr9000/windows/opencv_highgui341.dll
  20. BIN
      config/nvr9000/windows/opencv_imgcodecs341.dll
  21. BIN
      config/nvr9000/windows/opencv_imgproc341.dll
  22. BIN
      config/nvr9000/windows/opencv_objdetect341.dll
  23. BIN
      config/nvr9000/windows/opencv_videoio341.dll
  24. 159 0
      pom.xml
  25. 13 0
      src/main/java/com/persagy/MainApplication.java
  26. 109 0
      src/main/java/com/persagy/cameractl/conf/AllStaticConfig.java
  27. 51 0
      src/main/java/com/persagy/cameractl/conf/CameraConfig.java
  28. 130 0
      src/main/java/com/persagy/cameractl/conf/NVR9Config.java
  29. 19 0
      src/main/java/com/persagy/cameractl/conf/ServerConfig.java
  30. 108 0
      src/main/java/com/persagy/cameractl/controller/HelloController.java
  31. 38 0
      src/main/java/com/persagy/cameractl/init/SystemExit.java
  32. 109 0
      src/main/java/com/persagy/cameractl/init/SystemInit.java
  33. 13 0
      src/main/java/com/persagy/cameractl/init/Test.java
  34. 47 0
      src/main/java/com/persagy/cameractl/service/PtzMain.java
  35. 39 0
      src/main/java/com/persagy/cameractl/service/common/PaintPanel.java
  36. 188 0
      src/main/java/com/persagy/cameractl/service/windows/NVR9MainWindows.java
  37. 418 0
      src/main/java/com/persagy/cameractl/service/windows/ZhaosMainWindows.java
  38. 768 0
      src/main/java/com/persagy/cameractl/utils/Base64Util.java
  39. 521 0
      src/main/java/com/persagy/cameractl/utils/BaseNCodec.java
  40. 83 0
      src/main/java/com/persagy/cameractl/utils/Camera.java
  41. 12 0
      src/main/java/com/persagy/cameractl/utils/CameraLoop.java
  42. 63 0
      src/main/java/com/persagy/cameractl/utils/CmdStreamThread.java
  43. 9 0
      src/main/java/com/persagy/cameractl/utils/Constants.java
  44. 31 0
      src/main/java/com/persagy/cameractl/utils/DateUtil.java
  45. 63 0
      src/main/java/com/persagy/cameractl/utils/EnumTools.java
  46. 44 0
      src/main/java/com/persagy/cameractl/utils/JsonTools.java
  47. 24 0
      src/main/java/com/persagy/cameractl/utils/MimeCamera.java
  48. 138 0
      src/main/java/com/persagy/cameractl/utils/OtherTools.java
  49. 25 0
      src/main/java/com/persagy/cameractl/utils/ResultClass.java
  50. 71 0
      src/main/java/com/persagy/cameractl/utils/ResultTools.java
  51. 311 0
      src/main/java/com/persagy/cameractl/utils/StringTools.java
  52. 44 0
      src/main/java/com/persagy/cameractl/utils/TimerInterval.java
  53. 55 0
      src/main/java/com/persagy/nvr/DataPlayCallBackClass.java
  54. 86 0
      src/main/java/com/persagy/nvr/EndPlayCallBackClass.java
  55. 38 0
      src/main/java/com/persagy/nvr/FNVR_SYS_INFO.java
  56. 19 0
      src/main/java/com/persagy/nvr/FNVR_SYS_INFO_DSP.java
  57. 140 0
      src/main/java/com/persagy/nvr/GlobalExceptionHandler.java
  58. 60 0
      src/main/java/com/persagy/nvr/JavaStructBase.java
  59. 50 0
      src/main/java/com/persagy/nvr/MCAST_DEVICE_PACKET_EX.java
  60. 38 0
      src/main/java/com/persagy/nvr/NvrTest.java
  61. 281 0
      src/main/java/com/persagy/nvr/SdkMapper.java
  62. 9 0
      src/main/java/com/persagy/nvr/VIDEO_DETECT_TYPE.java
  63. 62 0
      src/main/java/com/persagy/nvr/VideoNoViskHeadFrameCallBackClass.java
  64. 3379 0
      src/main/java/com/persagy/nvr/VskClient.java
  65. 280 0
      src/main/java/com/persagy/vsknet/SdkMapper.java
  66. 53 0
      src/main/java/com/persagy/vsknet/Test.java
  67. 2281 0
      src/main/java/com/persagy/vsknet/VskDevNet.java
  68. 31 0
      src/main/java/com/persagy/vsknet/a59/NETS_59A_LIBRARY_INFO.java
  69. 28 0
      src/main/java/com/persagy/vsknet/a59/NETS_59A_UPGRADE_DEVICE_FILE.java
  70. 33 0
      src/main/java/com/persagy/vsknet/a59/NETS_59A_VERSION.java
  71. 49 0
      src/main/java/com/persagy/vsknet/enums/IPC_MACHINE_TYPE.java
  72. 43 0
      src/main/java/com/persagy/vsknet/net/NETUSER_INFO_64.java
  73. 23 0
      src/main/java/com/persagy/vsknet/net/NETUSER_LIST.java
  74. 29 0
      src/main/java/com/persagy/vsknet/net/NET_REPLY.java
  75. 45 0
      src/main/java/com/persagy/vsknet/net/NET_USER_INFO_REQ.java
  76. 36 0
      src/main/java/com/persagy/vsknet/net/NET_USER_PIC_INFO.java
  77. 31 0
      src/main/java/com/persagy/vsknet/net/NetAiAlarmInfoResponse.java
  78. 27 0
      src/main/java/com/persagy/vsknet/net/NetGetAIAlarmInfo.java
  79. 27 0
      src/main/java/com/persagy/vsknet/netsdk/NETSDK_AI_NET_ALARM_CONFIG_EXT.java
  80. 27 0
      src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_MixAIBaseConfig.java
  81. 40 0
      src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_MixAIQueryMotorRequset.java
  82. 44 0
      src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_MixAIQueryMotorResponse.java
  83. 40 0
      src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_MixAIQueryNonMotorRequset.java
  84. 44 0
      src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_MixAIQueryNonMotorResponse.java
  85. 40 0
      src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_MixAIQueryPeopleRequset.java
  86. 45 0
      src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_MixAIQueryPeopleResponse.java
  87. 83 0
      src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_MixAISubscibeRequest.java
  88. 36 0
      src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_MixAISubscibeResponseHeader.java
  89. 24 0
      src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_NetAIBagLeaveInfo.java
  90. 24 0
      src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_NetAIBannerInfo.java
  91. 59 0
      src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_NetAIMotorInfo.java
  92. 41 0
      src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_NetAINonMotorInfo.java
  93. 24 0
      src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_NetAIParaBoloidInfo.java
  94. 59 0
      src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_NetAIPeopleInfo.java
  95. 42 0
      src/main/java/com/persagy/vsknet/nvr/FNVR_SYS_INFO.java
  96. 24 0
      src/main/java/com/persagy/vsknet/nvr/FNVR_SYS_INFO_DSP.java
  97. 27 0
      src/main/java/com/persagy/vsknet/nvr/NVR_ALARM_INFO.java
  98. 26 0
      src/main/java/com/persagy/vsknet/nvr/NVR_CHANNEL_GB_ID.java
  99. 48 0
      src/main/java/com/persagy/vsknet/nvr/NVR_CHANNEL_PARA.java
  100. 0 0
      src/main/java/com/persagy/vsknet/nvr/NVR_DISK_INFO.java

BIN
config/lib/DecoderLib.dll


BIN
config/lib/G711SoundPlay.dll


BIN
config/lib/libfaac.dll


BIN
config/lib/libmp4v2.dll


BIN
config/lib/sdkJson.dll


BIN
config/lib/sdkJson.lib


BIN
config/lib/sdkJson.pdb


BIN
config/lib/sdkJson_new.dll


BIN
config/lib/sdkJson_old.dll


BIN
config/nvr9000/windows/DecoderLib.dll


BIN
config/nvr9000/windows/DecoderLib.lib


BIN
config/nvr9000/windows/DecoderLib.pdb


BIN
config/nvr9000/windows/G711SoundPlay.dll


BIN
config/nvr9000/windows/NSDEVNET.dll


BIN
config/nvr9000/windows/NSDEVNET.lib


BIN
config/nvr9000/windows/NSDEVNET.pdb


BIN
config/nvr9000/windows/nvrdemo


BIN
config/nvr9000/windows/opencv_core341.dll


BIN
config/nvr9000/windows/opencv_highgui341.dll


BIN
config/nvr9000/windows/opencv_imgcodecs341.dll


BIN
config/nvr9000/windows/opencv_imgproc341.dll


BIN
config/nvr9000/windows/opencv_objdetect341.dll


BIN
config/nvr9000/windows/opencv_videoio341.dll


+ 159 - 0
pom.xml

@@ -0,0 +1,159 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>com.persagy</groupId>
+	<artifactId>persagy-camera-zhaoshang</artifactId>
+	<version>1.0.0</version>
+	<description>摄像头监控</description>
+
+	<properties>
+		<!-- java版本 -->
+		<java.encoding>UTF-8</java.encoding>
+		<java.version>8</java.version>
+		<java.source.version>1.8</java.source.version>
+		<java.target.version>1.8</java.target.version>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+
+		<!-- spring版本依赖 -->
+		<integrated-platform.version>2.0.0</integrated-platform.version>
+		<spring-boot-dependencies.version>2.1.14.RELEASE</spring-boot-dependencies.version>
+		<spring-cloud-dependencies.version>Greenwich.SR6</spring-cloud-dependencies.version>
+	</properties>
+
+	<dependencyManagement>
+		<dependencies>
+			<dependency>
+				<groupId>com.persagy</groupId>
+				<artifactId>integrated-platform</artifactId>
+				<version>${integrated-platform.version}</version>
+				<type>pom</type>
+				<scope>import</scope>
+			</dependency>
+		</dependencies>
+	</dependencyManagement>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-web</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-test</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-context</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.kordamp.ezmorph</groupId>
+			<artifactId>ezmorph</artifactId>
+			<version>2.0.0</version>
+		</dependency>
+
+		<dependency>
+			<groupId>net.sf.json-lib</groupId>
+			<artifactId>json-lib</artifactId>
+			<version>2.4</version>
+			<classifier>jdk15</classifier>
+		</dependency>
+
+		<dependency>
+			<groupId>com.alibaba</groupId>
+			<artifactId>fastjson</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>cn.hutool</groupId>
+			<artifactId>hutool-all</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>net.java.dev.jna</groupId>
+			<artifactId>jna</artifactId>
+			<version>5.4.0</version>
+		</dependency>
+
+		<dependency>
+			<groupId>net.java.dev.jna</groupId>
+			<artifactId>jna-platform</artifactId>
+			<version>5.4.0</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.projectlombok</groupId>
+			<artifactId>lombok</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-configuration-processor</artifactId>
+		</dependency>
+	</dependencies>
+
+	<repositories>
+		<repository>
+			<id>nexus-aliyun</id>
+			<name>Nexus aliyun</name>
+			<layout>default</layout>
+			<url>http://maven.aliyun.com/nexus/content/groups/public</url>
+			<snapshots>
+				<enabled>false</enabled>
+			</snapshots>
+			<releases>
+				<enabled>true</enabled>
+			</releases>
+		</repository>
+		<repository>
+			<id>SagaCloud</id>
+			<name>SagaCloud</name>
+			<url>http://47.93.132.139:8081/nexus/content/groups/public/</url>
+			<snapshots>
+				<enabled>true</enabled>
+			</snapshots>
+			<releases>
+				<enabled>true</enabled>
+			</releases>
+		</repository>
+	</repositories>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-maven-plugin</artifactId>
+				<version>${spring-boot-dependencies.version}</version>
+			</plugin>
+		</plugins>
+		<resources>
+			<resource>
+				<directory>src/main/resources</directory>
+				<includes>
+					<include>**/*</include>
+					<include>*.yml</include>
+				</includes>
+			</resource>
+			<resource>
+				<directory>src/main/resources/jar</directory>
+				<targetPath>BOOT-INF/lib/</targetPath>
+				<includes>
+					<include>**/*.jar</include>
+				</includes>
+			</resource>
+			<resource>
+				<directory>src/main/resources</directory>
+				<targetPath>BOOT-INF/classes/</targetPath>
+			</resource>
+		</resources>
+	</build>
+
+</project>

+ 13 - 0
src/main/java/com/persagy/MainApplication.java

@@ -0,0 +1,13 @@
+package com.persagy;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class MainApplication {
+	
+	public static void main(String[] args) {
+		SpringApplication.run(MainApplication.class, args);
+	}
+	
+}

+ 109 - 0
src/main/java/com/persagy/cameractl/conf/AllStaticConfig.java

@@ -0,0 +1,109 @@
+package com.persagy.cameractl.conf;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.persagy.nvr.VideoNoViskHeadFrameCallBackClass;
+import com.persagy.nvr.DataPlayCallBackClass;
+import com.persagy.nvr.EndPlayCallBackClass;
+import com.persagy.nvr.VskClient;
+
+public class AllStaticConfig {
+	// 调用dll方法的实例
+	public static VskClient vskClient = null;
+
+	// 老版的回放视频数据的回调
+	public static DataPlayCallBackClass dataPlayCallBackClass = new DataPlayCallBackClass();
+
+	// 回放视频结束的回调
+	public static EndPlayCallBackClass endPlayCallBackClass = new EndPlayCallBackClass();
+
+	// 新版的回放视频数据的回放
+	public static VideoNoViskHeadFrameCallBackClass videoNoViskHeadFrameCallBackClass = new VideoNoViskHeadFrameCallBackClass();
+
+	// 存放回放视频数据的集合
+	public static List<byte[]> backByteBufferList = new ArrayList<byte[]>();
+
+	// 回放mp4生成的状态码,0 生成中 1 生成结束 2生成错误
+	public static int playBackMp4State = 1;
+
+	// 回放时生成的回放文件名称
+	public static String playBackFileName;
+
+	// 回放时生成的回放文件路径,包含文件名称
+	public static String playBackFilePath;
+	
+	public static String zhaoshangMesHost;
+
+	public static String zhaoshangApiIp;
+
+	public static String zhaoshangApiPort;
+
+	public static String bajiuSdkPort;
+
+	public static String zhaoshangApiKey;
+
+	public static String zhaoshangApiSecret;
+
+	public static String zhaoshangTvWallId;
+
+	public static String zhaoshangTvScreenId;
+
+	public static String getLibmp4v2Path() {
+		File directory = new File("./config/lib/libmp4v2.dll");
+		String filePath = "";
+		try {
+			filePath = directory.getCanonicalPath();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return filePath;
+	}
+
+	public static String getLibfaacPath() {
+		File directory = new File("./config/lib/libfaac.dll");
+		String filePath = "";
+		try {
+			filePath = directory.getCanonicalPath();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return filePath;
+	}
+
+	public static String getG711SoundPlayPath() {
+		File directory = new File("./config/lib/G711SoundPlay.dll");
+		String filePath = "";
+		try {
+			filePath = directory.getCanonicalPath();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return filePath;
+	}
+
+	public static String getDecoderLibPath() {
+		File directory = new File("./config/lib/DecoderLib.dll");
+		String filePath = "";
+		try {
+			filePath = directory.getCanonicalPath();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return filePath;
+	}
+
+	public static String getSdkJsonPath() {
+		File directory = new File("./config/lib/sdkJson.dll");
+		String filePath = "";
+		try {
+			filePath = directory.getCanonicalPath();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return filePath;
+	}
+
+}

+ 51 - 0
src/main/java/com/persagy/cameractl/conf/CameraConfig.java

@@ -0,0 +1,51 @@
+package com.persagy.cameractl.conf;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+@Component
+public class CameraConfig {
+	
+	@Value("${zhaoshang-config.mesHost}")
+	private String zhaoshangMesHost;
+	
+	@Value("${zhaoshang-config.baJiuApiIp}")
+	private String zhaoshangApiIp;
+	
+	@Value("${zhaoshang-config.baJiuApiPort}")
+	private String zhaoshangApiPort;
+	
+	@Value("${zhaoshang-config.bajiuSdkPort}")
+	private String bajiuSdkPort;
+	
+	@Value("${zhaoshang-config.appKey}")
+	private String zhaoshangApiKey;
+	
+	@Value("${zhaoshang-config.appSecret}")
+	private String zhaoshangApiSecret;
+	
+	@Value("${zhaoshang-config.tvWallId}")
+	private String zhaoshangTvWallId;
+	
+	@Value("${zhaoshang-config.tvScreenId}")
+	private String zhaoshangTvScreenId;
+	
+	
+	@Value("${nvr9-config.ip}")
+	private String nvr9Ip;
+	
+	@Value("${nvr9-config.port}")
+	private long nvr9Port;
+	
+	@Value("${nvr9-config.user-name}")
+	private String nvr9UserName;
+	
+	@Value("${nvr9-config.bajiuSdkPort}")
+	private String nvr9Password;
+
+}

+ 130 - 0
src/main/java/com/persagy/cameractl/conf/NVR9Config.java

@@ -0,0 +1,130 @@
+package com.persagy.cameractl.conf;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.persagy.vsknet.VskDevNet;
+import com.sun.jna.platform.win32.WinDef.UINT;
+
+/**
+ * NVR9000 配置类
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月29日 下午6:08:53
+ */
+public class NVR9Config {
+	/** 项目根路径 */
+	public static final String SERVER_ROOT_PATH = System.getProperty("user.dir");
+
+	/** NVR 9000 Client */
+	public static VskDevNet vskDevNet = null;
+	
+	public static final String DECODERLIB_DLL = "DecoderLib.dll";
+	public static final String DECODERLIB_LIB = "DecoderLib.lib";
+	public static final String DECODERLIB_PDB = "DecoderLib.pdb";
+	public static final String G711SOUNDPLAY_DLL = "G711SoundPlay.dll";
+	public static final String NSDEVNET_DLL = "NSDEVNET.dll";
+	public static final String NSDEVNET_LIB = "NSDEVNET.lib";
+	public static final String NSDEVNET_PDB = "NSDEVNET.pdb";
+	public static final String NVRDEMO = "nvrdemo";
+	public static final String OPENCV_CORE341_DLL = "opencv_core341.dll";
+	public static final String OPENCV_HIGHGUI341_DLL = "opencv_highgui341.dll";
+	public static final String OPENCV_IMGCODECS341_DLL = "opencv_imgcodecs341.dll";
+	public static final String OPENCV_IMGPROC341_DLL = "opencv_imgproc341.dll";
+	public static final String OPENCV_OBJDETECT341_DLL = "opencv_objdetect341.dll";
+	public static final String OPENCV_VIDEOIO341_DLL = "opencv_videoio341.dll";
+	
+	/**
+	 * 大屏的6种布局方式,分别是:
+	 * 1、一个窗口		2、九个窗口,其中左上角窗口跨两行两列	3、九个窗口,其中右下角窗口跨两行两列
+	 * 4、九个窗口,其中右上角窗口跨两行两列		5、九个窗口,其中左下角窗口跨两行两列	6、十二宫格
+	 */
+	public static final List<String> layoutNameList = new ArrayList<String>() {
+		private static final long serialVersionUID = 1L;
+		{
+			add("one");
+			add("left-up-one");
+			add("right-down-one");
+			add("right-up-one");
+			add("left-down-one");
+			add("multi-one");
+		}
+	};
+	
+	// 存放回放视频数据的集合
+	public static List<byte[]> backByteBufferList = new ArrayList<byte[]>();
+
+	// 回放mp4生成的状态码,0 生成中 1 生成结束 2生成错误
+	public static int playBackMp4State = 1;
+
+	// 回放时生成的回放文件名称
+	public static String playBackFileName;
+
+	// 回放时生成的回放文件路径,包含文件名称
+	public static String playBackFilePath;
+	
+	public static String nvr9Ip;
+	
+	public static long nvr9Port;
+	
+	public static String nvr9UserName;
+	
+	public static String nvr9Password;
+
+	/**
+	 * 获取指定的 dll 文件路径
+	 * 
+	 * @param dllName 文件名称,带后缀
+	 * @return
+	 * @date 2021年9月29日 下午3:23:37
+	 */
+	public static String getWindowsDllPath(String dllName) {
+		File directory = new File(SERVER_ROOT_PATH + "/config/nvr9000/windows/" + dllName);
+		String filePath = "";
+		try {
+			filePath = directory.getCanonicalPath();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return filePath;
+	}
+	
+	/**
+	 * 获取指定的 dll 文件路径
+	 * 
+	 * @param dllName 文件名称,带后缀
+	 * @return
+	 * @date 2021年9月29日 下午3:23:37
+	 */
+	public static String getLinuxDllPath(String dllName) {
+		File directory = new File(SERVER_ROOT_PATH + "/config/nvr9000/linux/" + dllName);
+		String filePath = "";
+		try {
+			filePath = directory.getCanonicalPath();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return filePath;
+	}
+	
+	/**
+	 * 获取异常码
+	 * 
+	 * @param dllName 文件名称,带后缀
+	 * @return
+	 * @date 2021年9月29日 下午3:23:37
+	 */
+	public static int getErrCode() {
+		try {
+			UINT lastErr = vskDevNet.NS_NET_GetLastErr();
+			return lastErr == null ? -1 : lastErr.intValue();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return -1;
+	}
+}

+ 19 - 0
src/main/java/com/persagy/cameractl/conf/ServerConfig.java

@@ -0,0 +1,19 @@
+package com.persagy.cameractl.conf;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ServerConfig {
+
+	@Value("${server.port}")
+	private int serverPort;
+
+	@Value("${server.servlet.context-path}")
+	private String contextPath;
+	
+	public String getUrl() {
+		return this.serverPort + this.contextPath;
+	}
+	
+}

+ 108 - 0
src/main/java/com/persagy/cameractl/controller/HelloController.java

@@ -0,0 +1,108 @@
+package com.persagy.cameractl.controller;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.OutputStream;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.persagy.cameractl.service.PtzMain;
+import com.persagy.cameractl.utils.Camera;
+import com.persagy.cameractl.utils.OtherTools;
+import com.persagy.cameractl.utils.ResultClass;
+import com.persagy.cameractl.utils.ResultTools;
+import com.persagy.cameractl.utils.StringTools;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Controller
+@CrossOrigin
+public class HelloController {
+
+	@RequestMapping(value = "/hello/{name}", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
+	public @ResponseBody String helloName(@PathVariable("name") String name) {
+
+		return ResultTools.errorResult(name);
+	}
+
+	/**
+	 * 摄像头操作接口(底层调用SDK),包括:摄像头控制、回放、查询SDK日志。客户端回放流程为:客户端先调用该接口,成功后再调用vplayf接口播放MP4
+	 * opertype为control时,参数:command、cameraIp、cameraPort、userName、password、channel、
+	 * speed
+	 * 
+	 * opertype为playback时,参数:cameraIp、cameraPort、userName、password、channel、
+	 * startDateStr、endDateStr
+	 * 
+	 * opertype为searchlog时,参数:cameraIp、cameraPort、userName、password、channel、
+	 * startDateStr、endDateStr
+	 */
+	@RequestMapping(value = "/sdk/{opertype}", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
+	public @ResponseBody String ptzOperation(@PathVariable("opertype") String operType, @RequestBody Camera _camera) {
+		PtzMain pcControlMain = new PtzMain();
+		ResultClass result = pcControlMain.ptzOper(_camera, operType);
+		switch (String.valueOf(result.name)) {
+			// 调用成功
+			case "true":
+				return ResultTools.dataResult(result.resultData);
+			// 调用失败
+			default:
+				return ResultTools.errorResult(result.reason);
+		}
+	}
+
+	/**
+	 * 请求视频文件接口
+	 */
+	@RequestMapping(value = "/vplayf/{token}", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
+	public @ResponseBody void vplay(@PathVariable("token") String token, HttpServletResponse response,
+			HttpServletRequest request) {
+//		String rangeStr=request.getHeader("Range");
+//		if(rangeStr.lastIndexOf("-")!=rangeStr.length()-1)
+//			return;
+		String filePath = OtherTools.getVideoFilePathByT(token);
+		if (filePath.equals(""))
+			return;
+		try {
+			File mp4File = new File(filePath);
+			if (!mp4File.exists())
+				return;
+			FileInputStream inputStream = new FileInputStream(filePath);
+			byte[] data = new byte[inputStream.available()];
+			inputStream.read(data);
+			String diskfilename = "_.mp4";
+			response.setContentType("video/mp4");
+			response.setHeader("Content-Disposition", "attachment; filename=\"" + diskfilename + "\"");
+			response.setContentLength(data.length);
+			// 支持分段请求
+//			response.setHeader("Accept-Ranges", "bytes");
+			// 不支持分段请求
+			response.setHeader("Accept-Ranges", "none");
+			// response.setHeader("Content-Range", "" + Integer.valueOf(data.length - 1));
+//			response.setHeader("Content-Range", "" + data.length);
+//			response.setHeader("Range", "bytes=0-" + data.length);
+//			response.setHeader("Content-Range", "bytes 0-" + data.length+"/"+data.length);
+			response.setHeader("Etag", "W/\"" + StringTools.getUUID() + "\"");
+			OutputStream os = response.getOutputStream();
+
+			os.write(data);
+			// 先声明的流后关掉!
+			os.flush();
+			os.close();
+			inputStream.close();
+
+		} catch (Exception e) {
+			log.error("播放" + token + "异常:", e);
+		}
+
+	}
+}

+ 38 - 0
src/main/java/com/persagy/cameractl/init/SystemExit.java

@@ -0,0 +1,38 @@
+package com.persagy.cameractl.init;
+
+import javax.annotation.PreDestroy;
+
+import org.springframework.stereotype.Component;
+
+import com.persagy.cameractl.conf.AllStaticConfig;
+import com.persagy.cameractl.conf.NVR9Config;
+
+import cn.hutool.core.util.BooleanUtil;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Component
+public class SystemExit {
+
+	@PreDestroy
+	public void exit() {
+		cleanUp();
+	}
+
+	/**
+	 * 释放加载的SDK
+	 * 
+	 * @date 2021年9月28日 上午10:25:29
+	 */
+	private void cleanUp() {
+		int clearResult = AllStaticConfig.vskClient.JsonSdk_Clear();
+		String consoleStr = clearResult == 0 ? "SDK释放成功" : "SDK释放失败,错误码:" + clearResult;
+		log.info(consoleStr);
+		
+		Boolean clear = NVR9Config.vskDevNet.NS_NET_Clear();
+		if (BooleanUtil.isTrue(clear)) {
+			log.info("release nvr9 success ");
+		}
+	}
+
+}

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

@@ -0,0 +1,109 @@
+package com.persagy.cameractl.init;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import com.persagy.cameractl.conf.AllStaticConfig;
+import com.persagy.cameractl.conf.CameraConfig;
+import com.persagy.cameractl.conf.NVR9Config;
+import com.persagy.cameractl.utils.TimerInterval;
+import com.persagy.nvr.SdkMapper;
+import com.persagy.nvr.VskClient;
+import com.persagy.vsknet.VskDevNet;
+import com.sun.jna.Library;
+import com.sun.jna.Native;
+
+import cn.hutool.core.util.BooleanUtil;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Order(1)
+@Component
+public class SystemInit implements ApplicationRunner {
+
+	@Autowired
+	private CameraConfig cameraConfig;
+
+	@Override
+	public void run(ApplicationArguments args) throws Exception {
+		AllStaticConfig.zhaoshangMesHost = cameraConfig.getZhaoshangMesHost();
+		AllStaticConfig.zhaoshangApiIp = cameraConfig.getZhaoshangApiIp();
+		AllStaticConfig.zhaoshangApiPort = cameraConfig.getZhaoshangApiPort();
+		AllStaticConfig.bajiuSdkPort = cameraConfig.getBajiuSdkPort();
+		AllStaticConfig.zhaoshangApiKey = cameraConfig.getZhaoshangApiKey();
+		AllStaticConfig.zhaoshangApiSecret = cameraConfig.getZhaoshangApiSecret();
+		AllStaticConfig.zhaoshangTvWallId = cameraConfig.getZhaoshangTvWallId();
+		AllStaticConfig.zhaoshangTvScreenId = cameraConfig.getZhaoshangTvScreenId();
+
+		// NVR9000
+		NVR9Config.nvr9Ip= cameraConfig.getNvr9Ip();
+		NVR9Config.nvr9Port= cameraConfig.getNvr9Port();
+		NVR9Config.nvr9UserName= cameraConfig.getNvr9UserName();
+		NVR9Config.nvr9Password= cameraConfig.getNvr9Password();
+		
+		this.initSdk();
+		this.setCustomCallBak();
+
+		log.info("init project success ...");
+
+		// 启动定时清除文件的定时器
+		TimerInterval.startClearFileTimer();
+	}
+
+	/**
+	 * 初始化SDK
+	 * 
+	 * @throws InstantiationException 
+	 * @date 2021年9月29日 下午8:38:35
+	 */
+	private void initSdk() throws InstantiationException {
+		// 加载必要类库
+		System.load(AllStaticConfig.getLibmp4v2Path());
+		System.load(AllStaticConfig.getLibfaacPath());
+		System.load(AllStaticConfig.getG711SoundPlayPath());
+		System.load(AllStaticConfig.getDecoderLibPath());
+		
+		// 初始化客户端
+		Map<String, Object> options = new HashMap<>();
+		options.put(Library.OPTION_FUNCTION_MAPPER, new SdkMapper());
+		AllStaticConfig.vskClient = (VskClient) Native.load(AllStaticConfig.getSdkJsonPath(), VskClient.class, options);
+		int initResult = AllStaticConfig.vskClient.JsonSdk_Initate();
+		if (initResult != 0) {
+			throw new InstantiationException("init SDKJsonDll failure:" + initResult);
+		}
+		
+		// 加载NVR9000 音频解码库
+		System.load(NVR9Config.getWindowsDllPath(NVR9Config.G711SOUNDPLAY_DLL));
+		
+		// 初始化客户端
+		Map<String, Object> nvr9Options = new HashMap<>();
+		nvr9Options.put(Library.OPTION_FUNCTION_MAPPER, new com.persagy.vsknet.SdkMapper());
+		
+		String windowsDllPath = NVR9Config.getWindowsDllPath(NVR9Config.NSDEVNET_DLL);
+		NVR9Config.vskDevNet = (VskDevNet) Native.load(windowsDllPath, VskDevNet.class);
+		Boolean initate = NVR9Config.vskDevNet.NS_NET_Initate();
+		if (!BooleanUtil.isTrue(initate)) {
+			throw new InstantiationException("init nvr900 SDK failure:" + initResult);
+		}
+	};
+
+	/**
+	 * 
+	 * @date 2021年9月29日 下午8:47:00
+	 */
+	private void setCustomCallBak() {
+		log.info("即将调用自定义设置回调");
+		int setCustomCallResult = AllStaticConfig.vskClient
+				.JsonSdk_SetVideoNoVskHeadFrameCallBack(AllStaticConfig.videoNoViskHeadFrameCallBackClass);
+		if (setCustomCallResult != 0) {
+			log.warn("自定义设置回调失败:" + setCustomCallResult);
+		}
+	}
+
+}

+ 13 - 0
src/main/java/com/persagy/cameractl/init/Test.java

@@ -0,0 +1,13 @@
+package com.persagy.cameractl.init;
+
+import com.sun.jna.Structure;
+import com.sun.jna.Structure.FieldOrder;
+
+@FieldOrder({"personName","personAge"})
+public class Test extends Structure{
+	
+	public String personName;
+	
+	public int personAge;
+	
+}

+ 47 - 0
src/main/java/com/persagy/cameractl/service/PtzMain.java

@@ -0,0 +1,47 @@
+package com.persagy.cameractl.service;
+
+import com.persagy.cameractl.service.windows.NVR9MainWindows;
+import com.persagy.cameractl.service.windows.ZhaosMainWindows;
+import com.persagy.cameractl.utils.Camera;
+import com.persagy.cameractl.utils.EnumTools.OperatingSystem;
+import com.persagy.cameractl.utils.OtherTools;
+import com.persagy.cameractl.utils.ResultClass;
+
+/**
+ * 摄像头相关调用的入口
+ */
+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();
+		}
+		
+		OperatingSystem systemName = OtherTools.getSystemName();
+		switch (systemName) {
+		case windows:
+			NVR9MainWindows nvr9MainWindows = new NVR9MainWindows(_camera);
+			return operType.equals("lx") ? nvr9MainWindows.lunx()
+					: OtherTools.executeErr("无效的操作类型");
+		default:
+			return OtherTools.executeErr("暂不支持");
+		}
+	};
+
+	/**
+	 * 摄像头实时播放入口
+	 */
+	public ResultClass realPlay(Camera _camera) {
+		return OtherTools.executeErr("暂不支持");
+	};
+
+}

+ 39 - 0
src/main/java/com/persagy/cameractl/service/common/PaintPanel.java

@@ -0,0 +1,39 @@
+package com.persagy.cameractl.service.common;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Image;
+
+import javax.swing.JPanel;
+
+/**
+ * 带背景的绘图面板
+ * 
+ * @author zhangqiankun
+ */
+public class PaintPanel extends JPanel {
+	private static final long serialVersionUID = 1L;
+
+	private Image image; // 背景图片
+
+	public PaintPanel() {
+		super();
+		setOpaque(true); // 非透明
+		setLayout(null);
+		setBackground(Color.GRAY);
+		setForeground(new Color(0, 0, 0));
+	}
+
+	// 设置图片的方法
+	public void setImage(Image image) {
+		this.image = image;
+	}
+
+	protected void paintComponent(Graphics g) { // 重写绘制组件外观
+		if (image != null) {
+			g.drawImage(image, 0, 0, getWidth(), getHeight(), this);// 绘制图片与组件大小相同
+		}
+		super.paintComponent(g); // 执行超类方法
+	}
+
+}

+ 188 - 0
src/main/java/com/persagy/cameractl/service/windows/NVR9MainWindows.java

@@ -0,0 +1,188 @@
+package com.persagy.cameractl.service.windows;
+
+import com.persagy.cameractl.conf.NVR9Config;
+import com.persagy.cameractl.utils.Camera;
+import com.persagy.cameractl.utils.CameraLoop;
+import com.persagy.cameractl.utils.OtherTools;
+import com.persagy.cameractl.utils.ResultClass;
+import com.persagy.vsknet.structure.DECV2_PROTO_DecCircleStrateryEx;
+import com.persagy.vsknet.structure.DECV2_PROTO_HEADER_T;
+import com.persagy.vsknet.structure.DecCircleStrateryEx;
+import com.persagy.vsknet.structure.DecCircleTimeEx;
+import com.persagy.vsknet.structure.IPC_ArrayEx;
+import com.persagy.vsknet.tmp.AUTHORIZATION;
+import com.persagy.vsknet.tmp.SERVER_URI;
+import com.sun.jna.platform.win32.WinDef;
+import com.sun.jna.platform.win32.WinDef.DWORD;
+import com.sun.jna.platform.win32.WinDef.UINT;
+
+import cn.hutool.core.util.BooleanUtil;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class NVR9MainWindows {
+
+	// 默认连接超时时间,单位:毫秒
+	int wait_time = 5000;
+
+	// 摄像头对象
+	Camera _camera;
+
+	// 登录句柄
+	DWORD loginHandler;
+
+	UINT login_id;
+
+	// 下载句柄
+	// LLong m_hDownLoadHandle = new LLong(0);
+
+	public NVR9MainWindows(Camera cameraI) {
+		this._camera = cameraI;
+	};
+
+	/**
+	 * 初始化及登录
+	 */
+	private ResultClass initAndLoginNVR9() {
+		if (NVR9Config.vskDevNet == null)
+			return this.executeErr(false, "NVR9 SDK未初始化成功,请重启应用程序", "");
+
+		// 登录
+		login_id = NVR9Config.vskDevNet.NS_NET_Login(NVR9Config.nvr9Ip.getBytes(), new WinDef.WORD(NVR9Config.nvr9Port),
+				NVR9Config.nvr9UserName.getBytes(), NVR9Config.nvr9Password.getBytes(), null, null);
+		long userId = login_id == null ? -1L : login_id.longValue();
+		if (userId < 0) {
+			return this.executeErr(false, userId + "", "登录失败");
+		}
+
+		ResultClass resultClass = new ResultClass();
+		resultClass.name = true;
+		return resultClass;
+	}
+
+	/**
+	 * 轮巡入口
+	 */
+	public ResultClass lunx() {
+		String layoutCode = _camera.layoutCode;
+		CameraLoop[] cameraLoopArr = _camera.cameraLoopArr;
+		if (layoutCode == null || "".equals(layoutCode) || cameraLoopArr == null || cameraLoopArr.length == 0) {
+			return this.executeErr(false, "非法的参数", "轮巡失败");
+		}
+		// 获取将要使用的布局方式
+		int currLayoutIndex = NVR9Config.layoutNameList.indexOf(layoutCode);
+		if (currLayoutIndex == -1) {
+			return this.executeErr(false, "非法的布局", "轮巡失败");
+		}
+
+		// 初始化
+		ResultClass initResult = this.initAndLoginNVR9();
+		if (!initResult.name) {
+			return this.executeErr(false, null, "初始化失败");
+		}
+
+		// 清屏、开窗操作
+		/**
+		 * String isOpenWindowResult = isOpenWindow(); if
+		 * (!isOpenWindowResult.equals("true")) { return this.executeErr(true,
+		 * isOpenWindowResult, "轮巡时:"); }
+		 */
+
+		for (int x = 0; x < cameraLoopArr.length; x++) {
+			CameraLoop _camerLoop = cameraLoopArr[x];
+
+			DECV2_PROTO_DecCircleStrateryEx DECV2_PROTO_DecCircleStrateryEx = new DECV2_PROTO_DecCircleStrateryEx();
+
+			DECV2_PROTO_HEADER_T proHead = new DECV2_PROTO_HEADER_T();
+			proHead.master = (byte) _camerLoop.windowId;
+
+			DecCircleStrateryEx decStratery = new DecCircleStrateryEx();
+			for (int y = 0; y < _camerLoop.videoSourceArr.length; y++) {
+				int channel = _camerLoop.videoSourceArr[y].channel;
+				int streamType = _camerLoop.videoSourceArr[y].streamType;	// 码流类型 0:主码流 ;	1:子码流 
+				
+				DecCircleTimeEx decCircleTimeEx = new DecCircleTimeEx();
+				decCircleTimeEx.nTimeId = 1;
+				decCircleTimeEx.uistarttime = 100;
+				decCircleTimeEx.uiendtime = 500;
+				decCircleTimeEx.nwinnum = 1;
+				decCircleTimeEx.nchanggeTime = 400;
+
+				IPC_ArrayEx ChlInfo = new IPC_ArrayEx();
+				SERVER_URI ipc = new SERVER_URI();
+				ipc.wChanUsed = 0;
+				ipc.channelID = (byte)channel;
+				ipc.ip = _camerLoop.videoSourceArr[y].cameraIp.getBytes();
+				ipc.port = _camerLoop.videoSourceArr[y].cameraPort;
+				ipc.frameRate = 25;
+				ipc.deviceType = 0;
+				if (streamType == 0) {
+				}
+				
+				AUTHORIZATION Ipclogin = new AUTHORIZATION();
+				Ipclogin.username = _camerLoop.videoSourceArr[y].userName.getBytes();
+				Ipclogin.password = _camerLoop.videoSourceArr[y].password.getBytes();
+
+				ChlInfo.ipc = ipc;
+				ChlInfo.Ipclogin = Ipclogin;
+				ChlInfo.nUser = (channel << 16 | _camerLoop.windowId);
+
+				decCircleTimeEx.ChlInfo[x + y] = ChlInfo;
+				decStratery.DecCircleStrateryChl[x][y] = decCircleTimeEx;
+			}
+
+			DECV2_PROTO_DecCircleStrateryEx.proHead = proHead;
+			DECV2_PROTO_DecCircleStrateryEx.decStratery = decStratery;
+
+			// NS_NET_SetNVRConfig
+			Boolean setResult = NVR9Config.vskDevNet.NS_NET_SetNVRConfig(login_id, new WinDef.UINT(140),
+					new WinDef.LONG(0xFFFFFFFF), DECV2_PROTO_DecCircleStrateryEx.getPointer(),
+					new WinDef.UINT(decStratery.size()));
+			if (!BooleanUtil.isTrue(setResult)) {
+				int errCode = NVR9Config.getErrCode();
+				return this.executeErr(true, "设置视频源轮巡失败,错误码:" + errCode + ",窗口号:" + _camerLoop.windowId, "");
+			}
+		}
+		return this.executeSuccess(null);
+	}
+
+	/**
+	 * 返回错误结果,同时释放资源 isLogingout 是否注销登录,在注册失败时只需要释放SDK不需要注销登录 errCode
+	 * 调用sdk的结果,一般为错误码 errPrefix 返回给客户端调用者的错误信息前缀
+	 * 
+	 * @param isLogingout
+	 * @param errCode
+	 * @param errPrefix
+	 * @return
+	 * @date 2021年9月30日 上午11:23:43
+	 */
+	private ResultClass executeErr(boolean isLogingout, String errCode, String errPrefix) {
+		this.sdkCleanup(isLogingout);
+		String errReason = OtherTools.joinErrStr(errCode, errPrefix);
+		return OtherTools.executeErr(errReason);
+	}
+
+	/**
+	 * 返回调用成功及结果数据,同时注销登陆
+	 */
+	private ResultClass executeSuccess(Object resultData) {
+		this.sdkCleanup(true);
+		return OtherTools.executeSuccess(resultData);
+	}
+
+	/**
+	 * 注销登录 isLogingout 是否注销登录,在注册失败时只需要释放SDK不需要注销登录
+	 */
+	private void sdkCleanup(boolean isLogingout) {
+		// 注销设备,即注销登录
+		if (isLogingout) {
+			Boolean logout = NVR9Config.vskDevNet.NS_NET_Logout(this.login_id);
+			if (BooleanUtil.isTrue(logout)) {
+				log.info("NVR9000 SDK 注销成功");
+			} else {
+				log.error("NVR9000 SDK 注销失败");
+			}
+		}
+	}
+
+}

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

@@ -0,0 +1,418 @@
+package com.persagy.cameractl.service.windows;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+
+import com.persagy.cameractl.conf.AllStaticConfig;
+import com.persagy.cameractl.utils.Camera;
+import com.persagy.cameractl.utils.DateUtil;
+import com.persagy.cameractl.utils.EnumTools;
+import com.persagy.cameractl.utils.JsonTools;
+import com.persagy.cameractl.utils.OtherTools;
+import com.persagy.cameractl.utils.ResultClass;
+import com.persagy.cameractl.utils.StringTools;
+import com.sun.jna.Memory;
+import com.sun.jna.Pointer;
+import com.sun.jna.platform.win32.WinDef;
+import com.sun.jna.platform.win32.WinDef.CHARByReference;
+import com.sun.jna.platform.win32.WinDef.DWORD;
+import com.sun.jna.platform.win32.WinDef.DWORDByReference;
+import com.sun.jna.platform.win32.WinDef.UINT;
+import com.sun.jna.platform.win32.WinDef.UINTByReference;
+
+import lombok.extern.slf4j.Slf4j;
+import sun.misc.BASE64Encoder;
+
+@Slf4j
+@SuppressWarnings("restriction")
+public class ZhaosMainWindows {
+	
+	// 默认连接超时时间,单位:毫秒
+	int wait_time = 5000;
+
+	// 摄像头对象
+	Camera _camera;
+	
+	// 登录句柄
+	DWORD loginHandler;
+
+	// 下载句柄
+	// LLong m_hDownLoadHandle = new LLong(0);
+
+	public ZhaosMainWindows(Camera cameraI) {
+		this._camera = cameraI;
+	};
+
+	/**
+	 * 返回错误结果,同时释放资源 isLogingout 是否注销登录,在注册失败时只需要释放SDK不需要注销登录 executeResult
+	 * 调用sdk的结果,一般为错误码 errPrefixString 返回给客户端调用者的错误信息前缀
+	 */
+	private ResultClass executeErr(boolean isLogingout, String executeResult, String errPrefixString) {
+		this.sdkCleanup(isLogingout);
+		String errReason = OtherTools.joinErrStr(executeResult, errPrefixString);
+		return OtherTools.executeErr(errReason);
+	};
+
+	/**
+	 * 返回调用成功及结果数据,同时注销登陆
+	 */
+	private ResultClass executeSuccess(Object resultData) {
+		this.sdkCleanup(true);
+		return OtherTools.executeSuccess(resultData);
+	};
+
+	/**
+	 * 注销登录、释放SDK isLogingout 是否注销登录,在注册失败时只需要释放SDK不需要注销登录
+	 */
+	private void sdkCleanup(boolean isLogingout) {
+		// 注销设备,即注销登录
+		if (isLogingout) {
+			int loginOutResult = AllStaticConfig.vskClient.JsonSdk_Logout(this.loginHandler);
+			if (loginOutResult != 0) {
+				log.error("注销失败,失败码:" + loginOutResult);
+			} else {
+				log.info("注销成功");
+			}
+		}
+		// 释放SDK, 因为在系统生命周期内,SDK只需要初始化一次,所以不需要释放
+		// hcNetSdk.NET_DVR_Cleanup();
+	};
+
+	/**
+	 * 登录
+	 * 
+	 * @return
+	 * @date 2021年9月28日 上午10:32:05
+	 */
+	private String login() {
+		try {
+			Map<String, String> userinfoMap = new HashMap<String, String>();
+			String userNameBase64 = new BASE64Encoder().encode(_camera.userName.getBytes());
+			String passwordBase64 = new BASE64Encoder().encode(_camera.password.getBytes());
+			userinfoMap.put("user_name", userNameBase64);
+			userinfoMap.put("password", passwordBase64);
+
+			Map<String, Object> loginInfoMap = new HashMap<String, Object>();
+			loginInfoMap.put("user_info", userinfoMap);
+			loginInfoMap.put("strNvrIp", _camera.cameraIp);
+			loginInfoMap.put("nNvrPort", _camera.cameraPort);
+
+			String pReqClientLoginStr = JsonTools.obj2Str(loginInfoMap);
+			// byte[] pReqClientLogin = pReqClientLoginStr.getBytes();
+			log.info("登录字符串:" + pReqClientLoginStr);
+
+			DWORD pnLoginDword = new DWORD(0);
+			DWORDByReference pnLoginID = new DWORDByReference(pnLoginDword);
+
+			int loginResult = AllStaticConfig.vskClient.JsonSdk_Login(pReqClientLoginStr, pnLoginID, null, null, null,
+					null);
+			if (loginResult != 0) {
+				return String.valueOf(loginResult);
+			}
+			loginHandler = pnLoginID.getValue();
+			return "true";
+		} catch (Exception e) {
+			log.error("登录时异常", e);
+			return "登录时异常";
+		}
+
+	};
+
+	/**
+	 * 初始化及登录
+	 */
+	private ResultClass initAndLogin() {
+		if (AllStaticConfig.vskClient == null)
+			return this.executeErr(false, "SdkJsonDll未初始化成功,请重启应用程序", "");
+
+		// 登录
+		String loginResult = this.login();
+		if (loginResult != "true") {
+			return this.executeErr(false, loginResult, "登录失败");
+		}
+
+		ResultClass resultClass = new ResultClass();
+		resultClass.name = true;
+		return resultClass;
+	}
+	
+	/**
+	 * 获得控制编码
+	 */
+	private int getControlCode() {
+		int codeIndex = EnumTools.listSdkCommand.indexOf(_camera.command);
+		return EnumTools.arrSdkCommandCode[codeIndex];
+	};
+
+	/**
+	 * 云台控制
+	 */
+	private String onPtzDirctCtrl() {
+		try {
+			int controlCode = getControlCode();
+			Map<String, Integer> reqPtzControlMap = new HashMap<String, Integer>();
+			reqPtzControlMap.put("chid", _camera.channel - 1);
+			reqPtzControlMap.put("ptz_cmd", controlCode);
+			reqPtzControlMap.put("value", _camera.speed);
+
+			String reqPtzControlStr = JsonTools.obj2Str(reqPtzControlMap);
+			log.info("执行控制命令时的串:" + reqPtzControlStr);
+			// byte[] reqPtzControlBytes = reqPtzControlStr.getBytes();
+			int controlResult = AllStaticConfig.vskClient.JsonSdk_PtzControl(this.loginHandler, reqPtzControlStr);
+			if (controlResult != 0) {
+				return String.valueOf(controlResult);
+			}
+			// 休眠1秒,即让云台执行1秒后再进行停止
+			Thread.sleep(1000);
+			// 再执行停止命令
+			reqPtzControlMap.put("value", 0);
+			String reqPtzControlStr2 = JsonTools.obj2Str(reqPtzControlMap);
+			log.info("停止执行控制命令时的串:" + reqPtzControlStr2);
+			// byte[] reqPtzControlBytes2 = reqPtzControlStr2.getBytes();
+			int controlResult2 = AllStaticConfig.vskClient.JsonSdk_PtzControl(this.loginHandler, reqPtzControlStr2);
+			if (controlResult2 != 0) {
+				return String.valueOf("控制停止时失败:" + controlResult2);
+			}
+
+			return "true";
+		} catch (Exception e) {
+			log.error("调用控制命令异常,控制命令:" + _camera.command, e);
+			return "调用控制命令异常";
+		}
+	}
+
+	/**
+	 * 视频回放
+	 */
+	private String startPlayBack() {
+		try {
+			Map<String, String> userinfoMap = new HashMap<String, String>();
+			String userNameBase64 = new BASE64Encoder().encode(_camera.userName.getBytes());
+			String passwordBase64 = new BASE64Encoder().encode(_camera.password.getBytes());
+			userinfoMap.put("user_name", userNameBase64);
+			userinfoMap.put("password", passwordBase64);
+
+			// 公元1970年1月1日0时0分0 秒算起至今的UTC时间所经过的秒数。
+			long startTimeSeconds = new DateUtil(_camera.startDateStr).getSecondsStart1970UTC();
+			long endTimeSeconds = new DateUtil(_camera.endDateStr).getSecondsStart1970UTC();
+
+			Map<String, Object> playbackStreamTimeMap = new HashMap<String, Object>();
+			playbackStreamTimeMap.put("chid", _camera.channel - 1);
+			playbackStreamTimeMap.put("stream_type", 0);
+			playbackStreamTimeMap.put("start_time", startTimeSeconds);
+			playbackStreamTimeMap.put("end_time", endTimeSeconds);
+			playbackStreamTimeMap.put("user_info", userinfoMap);
+
+			String pInfoStr = JsonTools.obj2Str(playbackStreamTimeMap);
+			// byte[] pInfo = pInfoStr.getBytes();
+
+			// int pUserValue = 2;
+			// pUserValue.getpo
+			String pUserValue = StringTools.getUUID();
+			Pointer pUserPointer = new Memory(40);
+			pUserPointer.setString(0, pUserValue);
+			WinDef.LPVOID pUser = new WinDef.LPVOID(pUserPointer);
+
+//			ULONGLONG pTotalSizeLong = new ULONGLONG(1);
+//			ULONGLONGByReference pTotalSize = new ULONGLONGByReference(pTotalSizeLong);
+
+			// DWORD playBackIdDWORD = new DWORD(Native.getNativeSize(DWORD.class));
+//			DWORD playBackIdDWORD = new DWORD(96);
+//			WinDef.DWORDByReference pnPlaybackID = new WinDef.DWORDByReference(playBackIdDWORD);
+
+			// Pointer pnPlaybackID = new Memory(20);
+
+			// if (_camera.isUseCustomCall == 1) {
+			//
+			// }
+
+			log.error("-----------即将调用JsonSdk_PlayBackStartByTime,串:" + pInfoStr);
+			log.error("loginHandler:" + loginHandler.intValue());
+			log.error("startTimeSeconds:" + startTimeSeconds + ",endTimeSeconds:" + endTimeSeconds);
+			// 发送根据时间进行回放的指令
+			// int playBackResult =
+			// AllStaticConfig.vskClient.JsonSdk_PlayBackStartByTime(loginHandler, pInfoStr,
+			// new DataPlayCallBackClass(), new EndPlayCallBackClass(), null, pUser,
+			// pTotalSize, pnPlaybackID);
+			int playBackResult = AllStaticConfig.vskClient.JsonSdk_PlayBackStartByTime(loginHandler, pInfoStr,
+					AllStaticConfig.dataPlayCallBackClass, AllStaticConfig.endPlayCallBackClass, null, pUser, null,
+					null);
+
+			if (playBackResult != 0) {
+				return String.valueOf(playBackResult);
+			}
+//			long pnPlaybackIdValue = pnPlaybackID.getValue().longValue();
+			AllStaticConfig.playBackMp4State = 0;
+			return "true";
+		} catch (Exception e) {
+			log.error("调用回放时异常:", e);
+			return "调用回放时异常";
+		}
+	};
+
+	/* 查询日志 */
+	private String searchLog() {
+		try {
+			// 公元1970年1月1日0时0分0 秒算起至今的UTC时间所经过的秒数。
+			long startTimeMillSeconds = new DateUtil(_camera.startDateStr).getSecondsStart1970UTC();
+			long endTimeMillSeconds = new DateUtil(_camera.endDateStr).getSecondsStart1970UTC();
+
+			Map<String, Object> sysLogMap = new HashMap<String, Object>();
+			sysLogMap.put("log_type", 1);
+			sysLogMap.put("act_time_begin", startTimeMillSeconds);
+			sysLogMap.put("act_time_end", endTimeMillSeconds);
+			String sysLogMapStr = JsonTools.obj2Str(sysLogMap);
+
+			UINT pnLogCountUint = new UINT(0);
+			UINTByReference pnLogCount = new UINTByReference(pnLogCountUint);
+
+			int searchLogResult = AllStaticConfig.vskClient.JsonSdk_QueryNVRLog(this.loginHandler, sysLogMapStr,
+					pnLogCount);
+			if (searchLogResult != 0) {
+				closeLog();
+				return String.valueOf("调用JsonSdk_QueryNVRLog失败:" + searchLogResult);
+			}
+
+			StringBuilder stringBuilder = new StringBuilder();
+			int logCoount = pnLogCount.getValue().intValue();
+			log.info("日志数量:" + logCoount);
+			for (int i = 0; i < logCoount; i++) {
+				CHARByReference pNvrLog = new CHARByReference();
+
+				UINT pNVRLogSizeUint = new UINT(0);
+				UINTByReference pNVRLogSize = new UINTByReference(pNVRLogSizeUint);
+
+				DWORD nextLogResult = AllStaticConfig.vskClient.JsonSdk_QueryNextLog(loginHandler, pNvrLog,
+						pNVRLogSize);
+				int nextLogResultInt = nextLogResult.intValue();
+				if (nextLogResultInt == 0) {
+					String string = pNvrLog.getValue().toString();
+					String string2 = pNvrLog.getPointer().getPointer(0).getString(0);
+					stringBuilder.append(string);
+					log.info("日志信息:");
+					log.info(string);
+					log.info(string2);
+				} else {
+					closeLog();
+					return String.valueOf("第" + (i) + "次调用JsonSdk_QueryNextLog失败:" + nextLogResultInt);
+				}
+			}
+
+			File sourceFile = new File("./logs/sdk.log");
+			sourceFile.createNewFile();// 有路径才能创建文件
+			FileOutputStream fos = new FileOutputStream(sourceFile);
+			fos.write(stringBuilder.toString().getBytes());
+			fos.close();
+
+			closeLog();
+			return "true";
+		} catch (Exception e) {
+			log.error("查询日志异常", e);
+			return "查询日志异常";
+		}
+	}
+
+	/**
+	 * 关闭日志查询
+	 */
+	private String closeLog() {
+		int result = AllStaticConfig.vskClient.JsonSdk_QueryLogClose(loginHandler);
+		return result == 0 ? "true" : String.valueOf(result);
+	}
+
+	/** 控制入口 */
+	public ResultClass controlMain() {
+		ResultClass initResultClass = initAndLogin();
+		if (!initResultClass.name)
+			return initResultClass;
+
+		String controlResult = onPtzDirctCtrl();
+		if (controlResult != "true") {
+			return this.executeErr(true, controlResult, "控制指令调用失败");
+		}
+		return this.executeSuccess(null);
+	};
+
+	/**
+	 * 回放入口 synchronized关键字即把方法改为同步,两个线程同时调用该方法时,上一个线程执行完后下一个线程才会执行
+	 */
+	public synchronized ResultClass playBackMain() {
+		try {
+			ResultClass returnResult = new ResultClass();
+			AllStaticConfig.playBackFilePath = OtherTools.getVideoFilePath();
+			if (AllStaticConfig.playBackFilePath.equals("")) {
+				returnResult.name = false;
+				returnResult.reason = "回放文件名称生成失败";
+				return returnResult;
+			}
+
+			File mp4File = new File(AllStaticConfig.playBackFilePath);
+			AllStaticConfig.playBackFileName = mp4File.getName();
+
+			String errPrefixStr = "回放失败";
+			// 初始化
+			ResultClass initResultClass = initAndLogin();
+			if (!initResultClass.name)
+				return initResultClass;
+
+			// 回放开始
+			String playBackResult = this.startPlayBack();
+			if (playBackResult != "true")
+				return this.executeErr(true, playBackResult, "执行回放时失败");
+
+			final CountDownLatch latch = new CountDownLatch(1);// 使用java并发库concurrent
+			new Thread(new Runnable() {
+				public void run() {
+					// 生成中
+					while (AllStaticConfig.playBackMp4State == 0) {
+						try {
+							Thread.sleep(1);
+						} catch (Exception e) {
+						}
+					}
+					latch.countDown();// 让latch中的数值减一
+
+				}
+			}).start();
+			try {
+				latch.await();// 阻塞当前线程直到latch中数值为零才执行
+				// 生成成功
+				if (AllStaticConfig.playBackMp4State == 1) {
+					log.info("正在拼接正常url");
+					String token = OtherTools.getMp4NamePrefix(AllStaticConfig.playBackFileName);
+					String url = OtherTools.playMp4RootUrl + token;
+					Map<String, String> dataMap = new HashMap<String, String>();
+					dataMap.put("url", url);
+					log.info("即将正常返回url");
+					return this.executeSuccess(dataMap);
+				}
+				log.info("errPrefixStr:" + errPrefixStr);
+				return this.executeErr(true, "视频文件生成失败", errPrefixStr);
+			} catch (Exception e) {
+				log.error("回放异常:", e);
+				return this.executeErr(true, "等待MP4生成异常", errPrefixStr);
+			}
+		} catch (Exception e) {
+			log.error("回放入口异常:", e);
+			return this.executeErr(true, "回放入口异常", "");
+		}
+
+	};
+
+	/** 查询日志入口 */
+	public ResultClass searchLogMain() {
+		ResultClass initResultClass = initAndLogin();
+		if (!initResultClass.name)
+			return initResultClass;
+
+		String searchResult = searchLog();
+		if (searchResult != "true") {
+			return this.executeErr(true, searchResult, "查询日志:");
+		}
+		return this.executeSuccess(null);
+	}
+
+}

+ 768 - 0
src/main/java/com/persagy/cameractl/utils/Base64Util.java

@@ -0,0 +1,768 @@
+package com.persagy.cameractl.utils;
+
+
+import java.math.BigInteger;
+
+/**
+ * Provides Base64 encoding and decoding as defined by <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>.
+ *
+ * <p>
+ * This class implements section <cite>6.8. Base64 Content-Transfer-Encoding</cite> from RFC 2045 <cite>Multipurpose
+ * Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies</cite> by Freed and Borenstein.
+ * </p>
+ * <p>
+ * The class can be parameterized in the following manner with various constructors:
+ * </p>
+ * <ul>
+ * <li>URL-safe mode: Default off.</li>
+ * <li>Line length: Default 76. Line length that aren't multiples of 4 will still essentially end up being multiples of
+ * 4 in the encoded data.
+ * <li>Line separator: Default is CRLF ("\r\n")</li>
+ * </ul>
+ * <p>
+ * The URL-safe parameter is only applied to encode operations. Decoding seamlessly handles both modes.
+ * </p>
+ * <p>
+ * Since this class operates directly on byte streams, and not character streams, it is hard-coded to only
+ * encode/decode character encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252,
+ * UTF-8, etc).
+ * </p>
+ * <p>
+ * This class is thread-safe.
+ * </p>
+ *
+ * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
+ * @since 1.0
+ * @version $Id: Base64.java 1635986 2014-11-01 16:27:52Z tn $
+ */
+public class Base64Util extends BaseNCodec {
+
+    /**
+     * BASE32 characters are 6 bits in length.
+     * They are formed by taking a block of 3 octets to form a 24-bit string,
+     * which is converted into 4 BASE64 characters.
+     */
+    private static final int BITS_PER_ENCODED_BYTE = 6;
+    private static final int BYTES_PER_UNENCODED_BLOCK = 3;
+    private static final int BYTES_PER_ENCODED_BLOCK = 4;
+
+    /**
+     * Chunk separator per RFC 2045 section 2.1.
+     *
+     * <p>
+     * N.B. The next major release may break compatibility and make this field private.
+     * </p>
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 2.1</a>
+     */
+    static final byte[] CHUNK_SEPARATOR = {'\r', '\n'};
+
+    /**
+     * This array is a lookup table that translates 6-bit positive integer index values into their "Base64 Alphabet"
+     * equivalents as specified in Table 1 of RFC 2045.
+     *
+     * Thanks to "commons" project in ws.apache.org for this code.
+     * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
+     */
+    private static final byte[] STANDARD_ENCODE_TABLE = {
+            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+            'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+            'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
+    };
+
+    /**
+     * This is a copy of the STANDARD_ENCODE_TABLE above, but with + and /
+     * changed to - and _ to make the encoded Base64 results more URL-SAFE.
+     * This table is only used when the Base64's mode is set to URL-SAFE.
+     */
+    private static final byte[] URL_SAFE_ENCODE_TABLE = {
+            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+            'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+            'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'
+    };
+
+    /**
+     * This array is a lookup table that translates Unicode characters drawn from the "Base64 Alphabet" (as specified
+     * in Table 1 of RFC 2045) into their 6-bit positive integer equivalents. Characters that are not in the Base64
+     * alphabet but fall within the bounds of the array are translated to -1.
+     *
+     * Note: '+' and '-' both decode to 62. '/' and '_' both decode to 63. This means decoder seamlessly handles both
+     * URL_SAFE and STANDARD base64. (The encoder, on the other hand, needs to know ahead of time what to emit).
+     *
+     * Thanks to "commons" project in ws.apache.org for this code.
+     * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
+     */
+    private static final byte[] DECODE_TABLE = {
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, 52, 53, 54,
+            55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4,
+            5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+            24, 25, -1, -1, -1, -1, 63, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+            35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
+    };
+
+    /**
+     * Base64 uses 6-bit fields.
+     */
+    /** Mask used to extract 6 bits, used when encoding */
+    private static final int MASK_6BITS = 0x3f;
+
+    // The static final fields above are used for the original static byte[] methods on Base64.
+    // The private member fields below are used with the new streaming approach, which requires
+    // some state be preserved between calls of encode() and decode().
+
+    /**
+     * Encode table to use: either STANDARD or URL_SAFE. Note: the DECODE_TABLE above remains static because it is able
+     * to decode both STANDARD and URL_SAFE streams, but the encodeTable must be a member variable so we can switch
+     * between the two modes.
+     */
+    private final byte[] encodeTable;
+
+    // Only one decode table currently; keep for consistency with Base32 code
+    private final byte[] decodeTable = DECODE_TABLE;
+
+    /**
+     * Line separator for encoding. Not used when decoding. Only used if lineLength &gt; 0.
+     */
+    private final byte[] lineSeparator;
+
+    /**
+     * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing.
+     * <code>decodeSize = 3 + lineSeparator.length;</code>
+     */
+    private final int decodeSize;
+
+    /**
+     * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing.
+     * <code>encodeSize = 4 + lineSeparator.length;</code>
+     */
+    private final int encodeSize;
+
+    /**
+     * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode.
+     * <p>
+     * When encoding the line length is 0 (no chunking), and the encoding table is STANDARD_ENCODE_TABLE.
+     * </p>
+     *
+     * <p>
+     * When decoding all variants are supported.
+     * </p>
+     */
+    public Base64Util() {
+        this(0);
+    }
+
+    /**
+     * Creates a Base64 codec used for decoding (all modes) and encoding in the given URL-safe mode.
+     * <p>
+     * When encoding the line length is 76, the line separator is CRLF, and the encoding table is STANDARD_ENCODE_TABLE.
+     * </p>
+     *
+     * <p>
+     * When decoding all variants are supported.
+     * </p>
+     *
+     * @param urlSafe
+     *            if <code>true</code>, URL-safe encoding is used. In most cases this should be set to
+     *            <code>false</code>.
+     * @since 1.4
+     */
+    public Base64Util(final boolean urlSafe) {
+        this(MIME_CHUNK_SIZE, CHUNK_SEPARATOR, urlSafe);
+    }
+
+    /**
+     * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode.
+     * <p>
+     * When encoding the line length is given in the constructor, the line separator is CRLF, and the encoding table is
+     * STANDARD_ENCODE_TABLE.
+     * </p>
+     * <p>
+     * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data.
+     * </p>
+     * <p>
+     * When decoding all variants are supported.
+     * </p>
+     *
+     * @param lineLength
+     *            Each line of encoded data will be at most of the given length (rounded down to nearest multiple of
+     *            4). If lineLength &lt;= 0, then the output will not be divided into lines (chunks). Ignored when
+     *            decoding.
+     * @since 1.4
+     */
+    public Base64Util(final int lineLength) {
+        this(lineLength, CHUNK_SEPARATOR);
+    }
+
+    /**
+     * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode.
+     * <p>
+     * When encoding the line length and line separator are given in the constructor, and the encoding table is
+     * STANDARD_ENCODE_TABLE.
+     * </p>
+     * <p>
+     * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data.
+     * </p>
+     * <p>
+     * When decoding all variants are supported.
+     * </p>
+     *
+     * @param lineLength
+     *            Each line of encoded data will be at most of the given length (rounded down to nearest multiple of
+     *            4). If lineLength &lt;= 0, then the output will not be divided into lines (chunks). Ignored when
+     *            decoding.
+     * @param lineSeparator
+     *            Each line of encoded data will end with this sequence of bytes.
+     * @throws IllegalArgumentException
+     *             Thrown when the provided lineSeparator included some base64 characters.
+     * @since 1.4
+     */
+    public Base64Util(final int lineLength, final byte[] lineSeparator) {
+        this(lineLength, lineSeparator, false);
+    }
+
+    /**
+     * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode.
+     * <p>
+     * When encoding the line length and line separator are given in the constructor, and the encoding table is
+     * STANDARD_ENCODE_TABLE.
+     * </p>
+     * <p>
+     * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data.
+     * </p>
+     * <p>
+     * When decoding all variants are supported.
+     * </p>
+     *
+     * @param lineLength
+     *            Each line of encoded data will be at most of the given length (rounded down to nearest multiple of
+     *            4). If lineLength &lt;= 0, then the output will not be divided into lines (chunks). Ignored when
+     *            decoding.
+     * @param lineSeparator
+     *            Each line of encoded data will end with this sequence of bytes.
+     * @param urlSafe
+     *            Instead of emitting '+' and '/' we emit '-' and '_' respectively. urlSafe is only applied to encode
+     *            operations. Decoding seamlessly handles both modes.
+     *            <b>Note: no padding is added when using the URL-safe alphabet.</b>
+     * @throws IllegalArgumentException
+     *             The provided lineSeparator included some base64 characters. That's not going to work!
+     * @since 1.4
+     */
+    public Base64Util(final int lineLength, final byte[] lineSeparator, final boolean urlSafe) {
+        super(BYTES_PER_UNENCODED_BLOCK, BYTES_PER_ENCODED_BLOCK,
+                lineLength,
+                lineSeparator == null ? 0 : lineSeparator.length);
+        // TODO could be simplified if there is no requirement to reject invalid line sep when length <=0
+        // @see test case Base64Test.testConstructors()
+        if (lineSeparator != null) {
+            if (containsAlphabetOrPad(lineSeparator)) {
+                final String sep = newStringUtf8(lineSeparator);
+                throw new IllegalArgumentException("lineSeparator must not contain base64 characters: [" + sep + "]");
+            }
+            if (lineLength > 0){ // null line-sep forces no chunking rather than throwing IAE
+                this.encodeSize = BYTES_PER_ENCODED_BLOCK + lineSeparator.length;
+                this.lineSeparator = new byte[lineSeparator.length];
+                System.arraycopy(lineSeparator, 0, this.lineSeparator, 0, lineSeparator.length);
+            } else {
+                this.encodeSize = BYTES_PER_ENCODED_BLOCK;
+                this.lineSeparator = null;
+            }
+        } else {
+            this.encodeSize = BYTES_PER_ENCODED_BLOCK;
+            this.lineSeparator = null;
+        }
+        this.decodeSize = this.encodeSize - 1;
+        this.encodeTable = urlSafe ? URL_SAFE_ENCODE_TABLE : STANDARD_ENCODE_TABLE;
+    }
+
+    /**
+     * Returns our current encode mode. True if we're URL-SAFE, false otherwise.
+     *
+     * @return true if we're in URL-SAFE mode, false otherwise.
+     * @since 1.4
+     */
+    public boolean isUrlSafe() {
+        return this.encodeTable == URL_SAFE_ENCODE_TABLE;
+    }
+
+    /**
+     * <p>
+     * Encodes all of the provided data, starting at inPos, for inAvail bytes. Must be called at least twice: once with
+     * the data to encode, and once with inAvail set to "-1" to alert encoder that EOF has been reached, to flush last
+     * remaining bytes (if not multiple of 3).
+     * </p>
+     * <p><b>Note: no padding is added when encoding using the URL-safe alphabet.</b></p>
+     * <p>
+     * Thanks to "commons" project in ws.apache.org for the bitwise operations, and general approach.
+     * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
+     * </p>
+     *
+     * @param in
+     *            byte[] array of binary data to base64 encode.
+     * @param inPos
+     *            Position to start reading data from.
+     * @param inAvail
+     *            Amount of bytes available from input for encoding.
+     * @param context
+     *            the context to be used
+     */
+    @Override
+    void encode(final byte[] in, int inPos, final int inAvail, final Context context) {
+        if (context.eof) {
+            return;
+        }
+        // inAvail < 0 is how we're informed of EOF in the underlying data we're
+        // encoding.
+        if (inAvail < 0) {
+            context.eof = true;
+            if (0 == context.modulus && lineLength == 0) {
+                return; // no leftovers to process and not using chunking
+            }
+            final byte[] buffer = ensureBufferSize(encodeSize, context);
+            final int savedPos = context.pos;
+            switch (context.modulus) { // 0-2
+                case 0 : // nothing to do here
+                    break;
+                case 1 : // 8 bits = 6 + 2
+                    // top 6 bits:
+                    buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 2) & MASK_6BITS];
+                    // remaining 2:
+                    buffer[context.pos++] = encodeTable[(context.ibitWorkArea << 4) & MASK_6BITS];
+                    // URL-SAFE skips the padding to further reduce size.
+                    if (encodeTable == STANDARD_ENCODE_TABLE) {
+                        buffer[context.pos++] = pad;
+                        buffer[context.pos++] = pad;
+                    }
+                    break;
+
+                case 2 : // 16 bits = 6 + 6 + 4
+                    buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 10) & MASK_6BITS];
+                    buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 4) & MASK_6BITS];
+                    buffer[context.pos++] = encodeTable[(context.ibitWorkArea << 2) & MASK_6BITS];
+                    // URL-SAFE skips the padding to further reduce size.
+                    if (encodeTable == STANDARD_ENCODE_TABLE) {
+                        buffer[context.pos++] = pad;
+                    }
+                    break;
+                default:
+                    throw new IllegalStateException("Impossible modulus "+context.modulus);
+            }
+            context.currentLinePos += context.pos - savedPos; // keep track of current line position
+            // if currentPos == 0 we are at the start of a line, so don't add CRLF
+            if (lineLength > 0 && context.currentLinePos > 0) {
+                System.arraycopy(lineSeparator, 0, buffer, context.pos, lineSeparator.length);
+                context.pos += lineSeparator.length;
+            }
+        } else {
+            for (int i = 0; i < inAvail; i++) {
+                final byte[] buffer = ensureBufferSize(encodeSize, context);
+                context.modulus = (context.modulus+1) % BYTES_PER_UNENCODED_BLOCK;
+                int b = in[inPos++];
+                if (b < 0) {
+                    b += 256;
+                }
+                context.ibitWorkArea = (context.ibitWorkArea << 8) + b; //  BITS_PER_BYTE
+                if (0 == context.modulus) { // 3 bytes = 24 bits = 4 * 6 bits to extract
+                    buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 18) & MASK_6BITS];
+                    buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 12) & MASK_6BITS];
+                    buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 6) & MASK_6BITS];
+                    buffer[context.pos++] = encodeTable[context.ibitWorkArea & MASK_6BITS];
+                    context.currentLinePos += BYTES_PER_ENCODED_BLOCK;
+                    if (lineLength > 0 && lineLength <= context.currentLinePos) {
+                        System.arraycopy(lineSeparator, 0, buffer, context.pos, lineSeparator.length);
+                        context.pos += lineSeparator.length;
+                        context.currentLinePos = 0;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * <p>
+     * Decodes all of the provided data, starting at inPos, for inAvail bytes. Should be called at least twice: once
+     * with the data to decode, and once with inAvail set to "-1" to alert decoder that EOF has been reached. The "-1"
+     * call is not necessary when decoding, but it doesn't hurt, either.
+     * </p>
+     * <p>
+     * Ignores all non-base64 characters. This is how chunked (e.g. 76 character) data is handled, since CR and LF are
+     * silently ignored, but has implications for other bytes, too. This method subscribes to the garbage-in,
+     * garbage-out philosophy: it will not check the provided data for validity.
+     * </p>
+     * <p>
+     * Thanks to "commons" project in ws.apache.org for the bitwise operations, and general approach.
+     * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
+     * </p>
+     *
+     * @param in
+     *            byte[] array of ascii data to base64 decode.
+     * @param inPos
+     *            Position to start reading data from.
+     * @param inAvail
+     *            Amount of bytes available from input for encoding.
+     * @param context
+     *            the context to be used
+     */
+    @Override
+    void decode(final byte[] in, int inPos, final int inAvail, final Context context) {
+        if (context.eof) {
+            return;
+        }
+        if (inAvail < 0) {
+            context.eof = true;
+        }
+        for (int i = 0; i < inAvail; i++) {
+            final byte[] buffer = ensureBufferSize(decodeSize, context);
+            final byte b = in[inPos++];
+            if (b == pad) {
+                // We're done.
+                context.eof = true;
+                break;
+            } else {
+                if (b >= 0 && b < DECODE_TABLE.length) {
+                    final int result = DECODE_TABLE[b];
+                    if (result >= 0) {
+                        context.modulus = (context.modulus+1) % BYTES_PER_ENCODED_BLOCK;
+                        context.ibitWorkArea = (context.ibitWorkArea << BITS_PER_ENCODED_BYTE) + result;
+                        if (context.modulus == 0) {
+                            buffer[context.pos++] = (byte) ((context.ibitWorkArea >> 16) & MASK_8BITS);
+                            buffer[context.pos++] = (byte) ((context.ibitWorkArea >> 8) & MASK_8BITS);
+                            buffer[context.pos++] = (byte) (context.ibitWorkArea & MASK_8BITS);
+                        }
+                    }
+                }
+            }
+        }
+
+        // Two forms of EOF as far as base64 decoder is concerned: actual
+        // EOF (-1) and first time '=' character is encountered in stream.
+        // This approach makes the '=' padding characters completely optional.
+        if (context.eof && context.modulus != 0) {
+            final byte[] buffer = ensureBufferSize(decodeSize, context);
+
+            // We have some spare bits remaining
+            // Output all whole multiples of 8 bits and ignore the rest
+            switch (context.modulus) {
+//              case 0 : // impossible, as excluded above
+                case 1 : // 6 bits - ignore entirely
+                    // TODO not currently tested; perhaps it is impossible?
+                    break;
+                case 2 : // 12 bits = 8 + 4
+                    context.ibitWorkArea = context.ibitWorkArea >> 4; // dump the extra 4 bits
+                    buffer[context.pos++] = (byte) ((context.ibitWorkArea) & MASK_8BITS);
+                    break;
+                case 3 : // 18 bits = 8 + 8 + 2
+                    context.ibitWorkArea = context.ibitWorkArea >> 2; // dump 2 bits
+                    buffer[context.pos++] = (byte) ((context.ibitWorkArea >> 8) & MASK_8BITS);
+                    buffer[context.pos++] = (byte) ((context.ibitWorkArea) & MASK_8BITS);
+                    break;
+                default:
+                    throw new IllegalStateException("Impossible modulus "+context.modulus);
+            }
+        }
+    }
+
+    /**
+     * Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. Currently the
+     * method treats whitespace as valid.
+     *
+     * @param arrayOctet
+     *            byte array to test
+     * @return <code>true</code> if all bytes are valid characters in the Base64 alphabet or if the byte array is empty;
+     *         <code>false</code>, otherwise
+     * @deprecated 1.5 Use {@link #isBase64(byte[])}, will be removed in 2.0.
+     */
+    @Deprecated
+    public static boolean isArrayByteBase64(final byte[] arrayOctet) {
+        return isBase64(arrayOctet);
+    }
+
+    /**
+     * Returns whether or not the <code>octet</code> is in the base 64 alphabet.
+     *
+     * @param octet
+     *            The value to test
+     * @return <code>true</code> if the value is defined in the the base 64 alphabet, <code>false</code> otherwise.
+     * @since 1.4
+     */
+    public static boolean isBase64(final byte octet) {
+        return octet == PAD_DEFAULT || (octet >= 0 && octet < DECODE_TABLE.length && DECODE_TABLE[octet] != -1);
+    }
+
+    /**
+     * Tests a given String to see if it contains only valid characters within the Base64 alphabet. Currently the
+     * method treats whitespace as valid.
+     *
+     * @param base64
+     *            String to test
+     * @return <code>true</code> if all characters in the String are valid characters in the Base64 alphabet or if
+     *         the String is empty; <code>false</code>, otherwise
+     *  @since 1.5
+     */
+    public static boolean isBase64(final String base64) {
+        return isBase64(getBytesUtf8(base64));
+    }
+
+    /**
+     * Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. Currently the
+     * method treats whitespace as valid.
+     *
+     * @param arrayOctet
+     *            byte array to test
+     * @return <code>true</code> if all bytes are valid characters in the Base64 alphabet or if the byte array is empty;
+     *         <code>false</code>, otherwise
+     * @since 1.5
+     */
+    public static boolean isBase64(final byte[] arrayOctet) {
+        for (int i = 0; i < arrayOctet.length; i++) {
+            if (!isBase64(arrayOctet[i]) && !isWhiteSpace(arrayOctet[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Encodes binary data using the base64 algorithm but does not chunk the output.
+     *
+     * @param binaryData
+     *            binary data to encode
+     * @return byte[] containing Base64 characters in their UTF-8 representation.
+     */
+    public static byte[] encodeBase64(final byte[] binaryData) {
+        return encodeBase64(binaryData, false);
+    }
+
+    /**
+     * Encodes binary data using the base64 algorithm but does not chunk the output.
+     *
+     * NOTE:  We changed the behaviour of this method from multi-line chunking (commons-codec-1.4) to
+     * single-line non-chunking (commons-codec-1.5).
+     *
+     * @param binaryData
+     *            binary data to encode
+     * @return String containing Base64 characters.
+     * @since 1.4 (NOTE:  1.4 chunked the output, whereas 1.5 does not).
+     */
+    public static String encodeBase64String(final byte[] binaryData) {
+        return newStringUtf8(encodeBase64(binaryData, false));
+    }
+
+    /**
+     * Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The
+     * url-safe variation emits - and _ instead of + and / characters.
+     * <b>Note: no padding is added.</b>
+     * @param binaryData
+     *            binary data to encode
+     * @return byte[] containing Base64 characters in their UTF-8 representation.
+     * @since 1.4
+     */
+    public static byte[] encodeBase64URLSafe(final byte[] binaryData) {
+        return encodeBase64(binaryData, false, true);
+    }
+
+    /**
+     * Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The
+     * url-safe variation emits - and _ instead of + and / characters.
+     * <b>Note: no padding is added.</b>
+     * @param binaryData
+     *            binary data to encode
+     * @return String containing Base64 characters
+     * @since 1.4
+     */
+    public static String encodeBase64URLSafeString(final byte[] binaryData) {
+        return newStringUtf8(encodeBase64(binaryData, false, true));
+    }
+
+    /**
+     * Encodes binary data using the base64 algorithm and chunks the encoded output into 76 character blocks
+     *
+     * @param binaryData
+     *            binary data to encode
+     * @return Base64 characters chunked in 76 character blocks
+     */
+    public static byte[] encodeBase64Chunked(final byte[] binaryData) {
+        return encodeBase64(binaryData, true);
+    }
+
+    /**
+     * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks.
+     *
+     * @param binaryData
+     *            Array containing binary data to encode.
+     * @param isChunked
+     *            if <code>true</code> this encoder will chunk the base64 output into 76 character blocks
+     * @return Base64-encoded data.
+     * @throws IllegalArgumentException
+     *             Thrown when the input array needs an output array bigger than {@link Integer#MAX_VALUE}
+     */
+    public static byte[] encodeBase64(final byte[] binaryData, final boolean isChunked) {
+        return encodeBase64(binaryData, isChunked, false);
+    }
+
+    /**
+     * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks.
+     *
+     * @param binaryData
+     *            Array containing binary data to encode.
+     * @param isChunked
+     *            if <code>true</code> this encoder will chunk the base64 output into 76 character blocks
+     * @param urlSafe
+     *            if <code>true</code> this encoder will emit - and _ instead of the usual + and / characters.
+     *            <b>Note: no padding is added when encoding using the URL-safe alphabet.</b>
+     * @return Base64-encoded data.
+     * @throws IllegalArgumentException
+     *             Thrown when the input array needs an output array bigger than {@link Integer#MAX_VALUE}
+     * @since 1.4
+     */
+    public static byte[] encodeBase64(final byte[] binaryData, final boolean isChunked, final boolean urlSafe) {
+        return encodeBase64(binaryData, isChunked, urlSafe, Integer.MAX_VALUE);
+    }
+
+    /**
+     * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks.
+     *
+     * @param binaryData
+     *            Array containing binary data to encode.
+     * @param isChunked
+     *            if <code>true</code> this encoder will chunk the base64 output into 76 character blocks
+     * @param urlSafe
+     *            if <code>true</code> this encoder will emit - and _ instead of the usual + and / characters.
+     *            <b>Note: no padding is added when encoding using the URL-safe alphabet.</b>
+     * @param maxResultSize
+     *            The maximum result size to accept.
+     * @return Base64-encoded data.
+     * @throws IllegalArgumentException
+     *             Thrown when the input array needs an output array bigger than maxResultSize
+     * @since 1.4
+     */
+    public static byte[] encodeBase64(final byte[] binaryData, final boolean isChunked,
+                                      final boolean urlSafe, final int maxResultSize) {
+        if (binaryData == null || binaryData.length == 0) {
+            return binaryData;
+        }
+
+        // Create this so can use the super-class method
+        // Also ensures that the same roundings are performed by the ctor and the code
+        final Base64Util b64 = isChunked ? new Base64Util(urlSafe) : new Base64Util(0, CHUNK_SEPARATOR, urlSafe);
+        final long len = b64.getEncodedLength(binaryData);
+        if (len > maxResultSize) {
+            throw new IllegalArgumentException("Input array too big, the output array would be bigger (" +
+                    len +
+                    ") than the specified maximum size of " +
+                    maxResultSize);
+        }
+
+        return b64.encode(binaryData);
+    }
+
+    /**
+     * Decodes a Base64 String into octets.
+     * <p>
+     * <b>Note:</b> this method seamlessly handles data encoded in URL-safe or normal mode.
+     * </p>
+     *
+     * @param base64String
+     *            String containing Base64 data
+     * @return Array containing decoded data.
+     * @since 1.4
+     */
+    public static byte[] decodeBase64(final String base64String) {
+        return new Base64Util().decode(base64String);
+    }
+
+    /**
+     * Decodes Base64 data into octets.
+     * <p>
+     * <b>Note:</b> this method seamlessly handles data encoded in URL-safe or normal mode.
+     * </p>
+     *
+     * @param base64Data
+     *            Byte array containing Base64 data
+     * @return Array containing decoded data.
+     */
+    public static byte[] decodeBase64(final byte[] base64Data) {
+        return new Base64Util().decode(base64Data);
+    }
+
+    // Implementation of the Encoder Interface
+
+    // Implementation of integer encoding used for crypto
+    /**
+     * Decodes a byte64-encoded integer according to crypto standards such as W3C's XML-Signature.
+     *
+     * @param pArray
+     *            a byte array containing base64 character data
+     * @return A BigInteger
+     * @since 1.4
+     */
+    public static BigInteger decodeInteger(final byte[] pArray) {
+        return new BigInteger(1, decodeBase64(pArray));
+    }
+
+    /**
+     * Encodes to a byte64-encoded integer according to crypto standards such as W3C's XML-Signature.
+     *
+     * @param bigInt
+     *            a BigInteger
+     * @return A byte array containing base64 character data
+     * @throws NullPointerException
+     *             if null is passed in
+     * @since 1.4
+     */
+    public static byte[] encodeInteger(final BigInteger bigInt) {
+        if (bigInt == null) {
+            throw new NullPointerException("encodeInteger called with null parameter");
+        }
+        return encodeBase64(toIntegerBytes(bigInt), false);
+    }
+
+    /**
+     * Returns a byte-array representation of a <code>BigInteger</code> without sign bit.
+     *
+     * @param bigInt
+     *            <code>BigInteger</code> to be converted
+     * @return a byte array representation of the BigInteger parameter
+     */
+    static byte[] toIntegerBytes(final BigInteger bigInt) {
+        int bitlen = bigInt.bitLength();
+        // round bitlen
+        bitlen = ((bitlen + 7) >> 3) << 3;
+        final byte[] bigBytes = bigInt.toByteArray();
+
+        if (((bigInt.bitLength() % 8) != 0) && (((bigInt.bitLength() / 8) + 1) == (bitlen / 8))) {
+            return bigBytes;
+        }
+        // set up params for copying everything but sign bit
+        int startSrc = 0;
+        int len = bigBytes.length;
+
+        // if bigInt is exactly byte-aligned, just skip signbit in copy
+        if ((bigInt.bitLength() % 8) == 0) {
+            startSrc = 1;
+            len--;
+        }
+        final int startDst = bitlen / 8 - len; // to pad w/ nulls as per spec
+        final byte[] resizedBytes = new byte[bitlen / 8];
+        System.arraycopy(bigBytes, startSrc, resizedBytes, startDst, len);
+        return resizedBytes;
+    }
+
+    /**
+     * Returns whether or not the <code>octet</code> is in the Base64 alphabet.
+     *
+     * @param octet
+     *            The value to test
+     * @return <code>true</code> if the value is defined in the the Base64 alphabet <code>false</code> otherwise.
+     */
+    @Override
+    protected boolean isInAlphabet(final byte octet) {
+        return octet >= 0 && octet < decodeTable.length && decodeTable[octet] != -1;
+    }
+
+}

+ 521 - 0
src/main/java/com/persagy/cameractl/utils/BaseNCodec.java

@@ -0,0 +1,521 @@
+package com.persagy.cameractl.utils;
+
+
+import java.nio.charset.Charset;
+import java.util.Arrays;
+
+/**
+ * Abstract superclass for Base-N encoders and decoders.
+ *
+ * <p>
+ * This class is thread-safe.
+ * </p>
+ *
+ * @version $Id: BaseNCodec.java 1634404 2014-10-26 23:06:10Z ggregory $
+ */
+public abstract class BaseNCodec {
+
+    /**
+     * Holds thread context so classes can be thread-safe.
+     *
+     * This class is not itself thread-safe; each thread must allocate its own copy.
+     *
+     * @since 1.7
+     */
+    static class Context {
+
+        /**
+         * Place holder for the bytes we're dealing with for our based logic.
+         * Bitwise operations store and extract the encoding or decoding from this variable.
+         */
+        int ibitWorkArea;
+
+        /**
+         * Place holder for the bytes we're dealing with for our based logic.
+         * Bitwise operations store and extract the encoding or decoding from this variable.
+         */
+        long lbitWorkArea;
+
+        /**
+         * Buffer for streaming.
+         */
+        byte[] buffer;
+
+        /**
+         * Position where next character should be written in the buffer.
+         */
+        int pos;
+
+        /**
+         * Position where next character should be read from the buffer.
+         */
+        int readPos;
+
+        /**
+         * Boolean flag to indicate the EOF has been reached. Once EOF has been reached, this object becomes useless,
+         * and must be thrown away.
+         */
+        boolean eof;
+
+        /**
+         * Variable tracks how many characters have been written to the current line. Only used when encoding. We use
+         * it to make sure each encoded line never goes beyond lineLength (if lineLength &gt; 0).
+         */
+        int currentLinePos;
+
+        /**
+         * Writes to the buffer only occur after every 3/5 reads when encoding, and every 4/8 reads when decoding. This
+         * variable helps track that.
+         */
+        int modulus;
+
+        Context() {
+        }
+
+        /**
+         * Returns a String useful for debugging (especially within a debugger.)
+         *
+         * @return a String useful for debugging.
+         */
+        @SuppressWarnings("boxing") // OK to ignore boxing here
+        public String toString() {
+            return String.format("%s[buffer=%s, currentLinePos=%s, eof=%s, ibitWorkArea=%s, lbitWorkArea=%s, " +
+                    "modulus=%s, pos=%s, readPos=%s]", this.getClass().getSimpleName(), Arrays.toString(buffer),
+                    currentLinePos, eof, ibitWorkArea, lbitWorkArea, modulus, pos, readPos);
+        }
+    }
+
+    /**
+     * EOF
+     *
+     * @since 1.7
+     */
+    static final int EOF = -1;
+
+    /**
+     *  MIME chunk size per RFC 2045 section 6.8.
+     *
+     * <p>
+     * The {@value} character limit does not count the trailing CRLF, but counts all other characters, including any
+     * equal signs.
+     * </p>
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 6.8</a>
+     */
+    public static final int MIME_CHUNK_SIZE = 76;
+
+    /**
+     * PEM chunk size per RFC 1421 section 4.3.2.4.
+     *
+     * <p>
+     * The {@value} character limit does not count the trailing CRLF, but counts all other characters, including any
+     * equal signs.
+     * </p>
+     *
+     * @see <a href="http://tools.ietf.org/html/rfc1421">RFC 1421 section 4.3.2.4</a>
+     */
+    public static final int PEM_CHUNK_SIZE = 64;
+
+    private static final int DEFAULT_BUFFER_RESIZE_FACTOR = 2;
+
+    /**
+     * Defines the default buffer size - currently {@value}
+     * - must be large enough for at least one encoded block+separator
+     */
+    private static final int DEFAULT_BUFFER_SIZE = 8192;
+
+    /** Mask used to extract 8 bits, used in decoding bytes */
+    protected static final int MASK_8BITS = 0xff;
+
+    /**
+     * Byte used to pad output.
+     */
+    protected static final byte PAD_DEFAULT = '='; // Allow static access to default
+
+    /**
+     * @deprecated Use {@link #pad}. Will be removed in 2.0.
+     */
+    @Deprecated
+    protected final byte PAD = PAD_DEFAULT; // instance variable just in case it needs to vary later
+
+    protected final byte pad; // instance variable just in case it needs to vary later
+
+    /** Number of bytes in each full block of unencoded data, e.g. 4 for Base64 and 5 for Base32 */
+    private final int unencodedBlockSize;
+
+    /** Number of bytes in each full block of encoded data, e.g. 3 for Base64 and 8 for Base32 */
+    private final int encodedBlockSize;
+
+    /**
+     * Chunksize for encoding. Not used when decoding.
+     * A value of zero or less implies no chunking of the encoded data.
+     * Rounded down to nearest multiple of encodedBlockSize.
+     */
+    protected final int lineLength;
+
+    /**
+     * Size of chunk separator. Not used unless {@link #lineLength} &gt; 0.
+     */
+    private final int chunkSeparatorLength;
+
+    /**
+     * Note <code>lineLength</code> is rounded down to the nearest multiple of {@link #encodedBlockSize}
+     * If <code>chunkSeparatorLength</code> is zero, then chunking is disabled.
+     * @param unencodedBlockSize the size of an unencoded block (e.g. Base64 = 3)
+     * @param encodedBlockSize the size of an encoded block (e.g. Base64 = 4)
+     * @param lineLength if &gt; 0, use chunking with a length <code>lineLength</code>
+     * @param chunkSeparatorLength the chunk separator length, if relevant
+     */
+    protected BaseNCodec(final int unencodedBlockSize, final int encodedBlockSize,
+                         final int lineLength, final int chunkSeparatorLength) {
+        this(unencodedBlockSize, encodedBlockSize, lineLength, chunkSeparatorLength, PAD_DEFAULT);
+    }
+
+    /**
+     * Note <code>lineLength</code> is rounded down to the nearest multiple of {@link #encodedBlockSize}
+     * If <code>chunkSeparatorLength</code> is zero, then chunking is disabled.
+     * @param unencodedBlockSize the size of an unencoded block (e.g. Base64 = 3)
+     * @param encodedBlockSize the size of an encoded block (e.g. Base64 = 4)
+     * @param lineLength if &gt; 0, use chunking with a length <code>lineLength</code>
+     * @param chunkSeparatorLength the chunk separator length, if relevant
+     * @param pad byte used as padding byte.
+     */
+    protected BaseNCodec(final int unencodedBlockSize, final int encodedBlockSize,
+                         final int lineLength, final int chunkSeparatorLength, final byte pad) {
+        this.unencodedBlockSize = unencodedBlockSize;
+        this.encodedBlockSize = encodedBlockSize;
+        final boolean useChunking = lineLength > 0 && chunkSeparatorLength > 0;
+        this.lineLength = useChunking ? (lineLength / encodedBlockSize) * encodedBlockSize : 0;
+        this.chunkSeparatorLength = chunkSeparatorLength;
+
+        this.pad = pad;
+    }
+
+    /**
+     * Returns true if this object has buffered data for reading.
+     *
+     * @param context the context to be used
+     * @return true if there is data still available for reading.
+     */
+    boolean hasData(final Context context) {  // package protected for access from I/O streams
+        return context.buffer != null;
+    }
+
+    /**
+     * Returns the amount of buffered data available for reading.
+     *
+     * @param context the context to be used
+     * @return The amount of buffered data available for reading.
+     */
+    int available(final Context context) {  // package protected for access from I/O streams
+        return context.buffer != null ? context.pos - context.readPos : 0;
+    }
+
+    /**
+     * Get the default buffer size. Can be overridden.
+     *
+     * @return {@link #DEFAULT_BUFFER_SIZE}
+     */
+    protected int getDefaultBufferSize() {
+        return DEFAULT_BUFFER_SIZE;
+    }
+
+    /**
+     * Increases our buffer by the {@link #DEFAULT_BUFFER_RESIZE_FACTOR}.
+     * @param context the context to be used
+     */
+    private byte[] resizeBuffer(final Context context) {
+        if (context.buffer == null) {
+            context.buffer = new byte[getDefaultBufferSize()];
+            context.pos = 0;
+            context.readPos = 0;
+        } else {
+            final byte[] b = new byte[context.buffer.length * DEFAULT_BUFFER_RESIZE_FACTOR];
+            System.arraycopy(context.buffer, 0, b, 0, context.buffer.length);
+            context.buffer = b;
+        }
+        return context.buffer;
+    }
+
+    /**
+     * Ensure that the buffer has room for <code>size</code> bytes
+     *
+     * @param size minimum spare space required
+     * @param context the context to be used
+     * @return the buffer
+     */
+    protected byte[] ensureBufferSize(final int size, final Context context){
+        if ((context.buffer == null) || (context.buffer.length < context.pos + size)){
+            return resizeBuffer(context);
+        }
+        return context.buffer;
+    }
+
+    /**
+     * Extracts buffered data into the provided byte[] array, starting at position bPos, up to a maximum of bAvail
+     * bytes. Returns how many bytes were actually extracted.
+     * <p>
+     * Package protected for access from I/O streams.
+     *
+     * @param b
+     *            byte[] array to extract the buffered data into.
+     * @param bPos
+     *            position in byte[] array to start extraction at.
+     * @param bAvail
+     *            amount of bytes we're allowed to extract. We may extract fewer (if fewer are available).
+     * @param context
+     *            the context to be used
+     * @return The number of bytes successfully extracted into the provided byte[] array.
+     */
+    int readResults(final byte[] b, final int bPos, final int bAvail, final Context context) {
+        if (context.buffer != null) {
+            final int len = Math.min(available(context), bAvail);
+            System.arraycopy(context.buffer, context.readPos, b, bPos, len);
+            context.readPos += len;
+            if (context.readPos >= context.pos) {
+                context.buffer = null; // so hasData() will return false, and this method can return -1
+            }
+            return len;
+        }
+        return context.eof ? EOF : 0;
+    }
+
+    /**
+     * Checks if a byte value is whitespace or not.
+     * Whitespace is taken to mean: space, tab, CR, LF
+     * @param byteToCheck
+     *            the byte to check
+     * @return true if byte is whitespace, false otherwise
+     */
+    protected static boolean isWhiteSpace(final byte byteToCheck) {
+        switch (byteToCheck) {
+            case ' ' :
+            case '\n' :
+            case '\r' :
+            case '\t' :
+                return true;
+            default :
+                return false;
+        }
+    }
+
+    /**
+     * Encodes an Object using the Base-N algorithm. This method is provided in order to satisfy the requirements of
+     * the Encoder interface, and will throw an EncoderException if the supplied object is not of type byte[].
+     *
+     * @param obj
+     *            Object to encode
+     * @return An object (of type byte[]) containing the Base-N encoded data which corresponds to the byte[] supplied.
+     * @throws Exception
+     *             if the parameter supplied is not of type byte[]
+     */
+    public Object encode(final Object obj) throws Exception {
+        if (!(obj instanceof byte[])) {
+            throw new Exception("Parameter supplied to Base-N encode is not a byte[]");
+        }
+        return encode((byte[]) obj);
+    }
+
+    /**
+     * Encodes a byte[] containing binary data, into a String containing characters in the Base-N alphabet.
+     * Uses UTF8 encoding.
+     *
+     * @param pArray
+     *            a byte array containing binary data
+     * @return A String containing only Base-N character data
+     */
+    public String encodeToString(final byte[] pArray) {
+        return newStringUtf8(encode(pArray));
+    }
+
+    /**
+     * Encodes a byte[] containing binary data, into a String containing characters in the appropriate alphabet.
+     * Uses UTF8 encoding.
+     *
+     * @param pArray a byte array containing binary data
+     * @return String containing only character data in the appropriate alphabet.
+    */
+    public String encodeAsString(final byte[] pArray){
+        return newStringUtf8(encode(pArray));
+    }
+
+    /**
+     * Decodes an Object using the Base-N algorithm. This method is provided in order to satisfy the requirements of
+     * the Decoder interface, and will throw a DecoderException if the supplied object is not of type byte[] or String.
+     *
+     * @param obj
+     *            Object to decode
+     * @return An object (of type byte[]) containing the binary data which corresponds to the byte[] or String
+     *         supplied.
+     * @throws Exception
+     *             if the parameter supplied is not of type byte[]
+     */
+    public Object decode(final Object obj) throws Exception {
+        if (obj instanceof byte[]) {
+            return decode((byte[]) obj);
+        } else if (obj instanceof String) {
+            return decode((String) obj);
+        } else {
+            throw new Exception("Parameter supplied to Base-N decode is not a byte[] or a String");
+        }
+    }
+
+    /**
+     * Decodes a String containing characters in the Base-N alphabet.
+     *
+     * @param pArray
+     *            A String containing Base-N character data
+     * @return a byte array containing binary data
+     */
+    public byte[] decode(final String pArray) {
+        return decode(getBytesUtf8(pArray));
+    }
+
+    /**
+     * Decodes a byte[] containing characters in the Base-N alphabet.
+     *
+     * @param pArray
+     *            A byte array containing Base-N character data
+     * @return a byte array containing binary data
+     */
+    public byte[] decode(final byte[] pArray) {
+        if (pArray == null || pArray.length == 0) {
+            return pArray;
+        }
+        final Context context = new Context();
+        decode(pArray, 0, pArray.length, context);
+        decode(pArray, 0, EOF, context); // Notify decoder of EOF.
+        final byte[] result = new byte[context.pos];
+        readResults(result, 0, result.length, context);
+        return result;
+    }
+
+    /**
+     * Encodes a byte[] containing binary data, into a byte[] containing characters in the alphabet.
+     *
+     * @param pArray
+     *            a byte array containing binary data
+     * @return A byte array containing only the basen alphabetic character data
+     */
+    public byte[] encode(final byte[] pArray) {
+        if (pArray == null || pArray.length == 0) {
+            return pArray;
+        }
+        final Context context = new Context();
+        encode(pArray, 0, pArray.length, context);
+        encode(pArray, 0, EOF, context); // Notify encoder of EOF.
+        final byte[] buf = new byte[context.pos - context.readPos];
+        readResults(buf, 0, buf.length, context);
+        return buf;
+    }
+
+    // package protected for access from I/O streams
+    abstract void encode(byte[] pArray, int i, int length, Context context);
+
+    // package protected for access from I/O streams
+    abstract void decode(byte[] pArray, int i, int length, Context context);
+
+    /**
+     * Returns whether or not the <code>octet</code> is in the current alphabet.
+     * Does not allow whitespace or pad.
+     *
+     * @param value The value to test
+     *
+     * @return <code>true</code> if the value is defined in the current alphabet, <code>false</code> otherwise.
+     */
+    protected abstract boolean isInAlphabet(byte value);
+
+    /**
+     * Tests a given byte array to see if it contains only valid characters within the alphabet.
+     * The method optionally treats whitespace and pad as valid.
+     *
+     * @param arrayOctet byte array to test
+     * @param allowWSPad if <code>true</code>, then whitespace and PAD are also allowed
+     *
+     * @return <code>true</code> if all bytes are valid characters in the alphabet or if the byte array is empty;
+     *         <code>false</code>, otherwise
+     */
+    public boolean isInAlphabet(final byte[] arrayOctet, final boolean allowWSPad) {
+        for (int i = 0; i < arrayOctet.length; i++) {
+            if (!isInAlphabet(arrayOctet[i]) &&
+                    (!allowWSPad || (arrayOctet[i] != pad) && !isWhiteSpace(arrayOctet[i]))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Tests a given String to see if it contains only valid characters within the alphabet.
+     * The method treats whitespace and PAD as valid.
+     *
+     * @param basen String to test
+     * @return <code>true</code> if all characters in the String are valid characters in the alphabet or if
+     *         the String is empty; <code>false</code>, otherwise
+     * @see #isInAlphabet(byte[], boolean)
+     */
+    public boolean isInAlphabet(final String basen) {
+        return isInAlphabet(getBytesUtf8(basen), true);
+    }
+
+    /**
+     * Tests a given byte array to see if it contains any characters within the alphabet or PAD.
+     *
+     * Intended for use in checking line-ending arrays
+     *
+     * @param arrayOctet
+     *            byte array to test
+     * @return <code>true</code> if any byte is a valid character in the alphabet or PAD; <code>false</code> otherwise
+     */
+    protected boolean containsAlphabetOrPad(final byte[] arrayOctet) {
+        if (arrayOctet == null) {
+            return false;
+        }
+        for (final byte element : arrayOctet) {
+            if (pad == element || isInAlphabet(element)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Calculates the amount of space needed to encode the supplied array.
+     *
+     * @param pArray byte[] array which will later be encoded
+     *
+     * @return amount of space needed to encoded the supplied array.
+     * Returns a long since a max-len array will require &gt; Integer.MAX_VALUE
+     */
+    public long getEncodedLength(final byte[] pArray) {
+        // Calculate non-chunked size - rounded up to allow for padding
+        // cast to long is needed to avoid possibility of overflow
+        long len = ((pArray.length + unencodedBlockSize-1)  / unencodedBlockSize) * (long) encodedBlockSize;
+        if (lineLength > 0) { // We're using chunking
+            // Round up to nearest multiple
+            len += ((len + lineLength-1) / lineLength) * chunkSeparatorLength;
+        }
+        return len;
+    }
+
+    public static Charset UTF8 = Charset.forName("UTF-8");
+
+    public static String newStringUtf8(byte[] bytes) {
+        return newString(bytes, UTF8);
+    }
+
+    private static String newString(final byte[] bytes, final Charset charset) {
+        return bytes == null ? null : new String(bytes, charset);
+    }
+
+    public static byte[] getBytesUtf8(final String string) {
+        return getBytes(string, UTF8);
+    }
+
+    private static byte[] getBytes(final String string, final Charset charset) {
+        if (string == null) {
+            return null;
+        }
+        return string.getBytes(charset);
+    }
+}

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

@@ -0,0 +1,83 @@
+package com.persagy.cameractl.utils;
+
+/**
+ * 摄像头对象
+ * */
+public class Camera {
+	
+	// 通道号 1~32表示模拟通道,9000系列混合型DVR和NVR等设备的IP通道从33开始(即程序用的通道号为33+通道号-1)。回放、实时播放、控制使用
+	public int channel = 1;
+
+	// 码流类型 0:主码流 1:子码流 2:第三码流 参数不填,默认为子码流
+	public int streamType = 1;
+
+	// 命令类型,参见EnumTool.listSdkCommand
+	public String command;
+
+	// 开始还是停止 true 开始 false 停止
+	public Boolean dwStop = true;
+
+	// 调用硬件SDK时值范围1~100,默认50。指上仰下俯的速度、左转右转的速度、左上左下右上右下的水平速度
+	public int speed = 50;
+
+	// 摄像头IP
+	public String cameraIp;
+
+	// 摄像头服务端口号
+	public int cameraPort = 8000;
+
+	// 登录用户名
+	public String userName = "admin";
+
+	// 登录密码
+	// pelco123
+	public String password;
+
+	// 开始时间,用于回放。格式:2021-03-01 15:02:11
+	public String startDateStr;
+
+	// 结束时间,用于回放。格式:2021-03-01 15:02:11
+	public String endDateStr;
+
+	// 通道ID
+	public String cameraIndexCode;
+	
+	//窗口ID
+	public int windowId;
+
+	// 接口名称,方便客户端调用
+	public String url;
+
+	// 放入{_type:"get | post",interfaceId:"可为空",isToken:"1 | 0"}
+	public String paramStr;
+	
+	//电视墙ID
+	public int tvWallId=-1;
+	
+	/*
+	 * 布局编码,取值范围:
+	 * 	one(只有一个窗口)、left-up-one(六个窗口,左上角是大窗口)、
+	 * 	right-down-one(六个窗口,右下角是大窗口)、right-up-one(六个窗口,右上角是大窗口)、
+	 * 	left-down-one(六个窗口,左下角是大窗口)、multi-one(九宫格窗口)
+	 * */
+	public String layoutCode;
+	
+	//视频墙数据源数组,每一项均为cameraIndexCode,数组的顺序和窗口顺序保持一致
+	public String[] cameraIndexArr;
+
+	/*------------------以下为大华特有的----------------*/
+
+	// 级联号
+	public String levelNo;
+
+	// 垂直速度,大华特有,左上左下右上右下操作时使用,值范围1~8,默认8
+	public int verSpeed = 8;
+
+	// 8900平台接口所需要的参数
+	public String jsonParam;
+	
+	public int isUseCustomCall=0;
+	
+	public CameraLoop[] cameraLoopArr;
+
+}

+ 12 - 0
src/main/java/com/persagy/cameractl/utils/CameraLoop.java

@@ -0,0 +1,12 @@
+package com.persagy.cameractl.utils;
+
+public class CameraLoop {
+	// 轮巡时间,单位秒,默认10秒
+	public int loopTime = 10;
+
+	// 窗口ID,从1开始,依次+1
+	public int windowId;
+
+	// 视频数据源数组,每一项均为MimeCamera
+	public MimeCamera[] videoSourceArr;
+}

+ 63 - 0
src/main/java/com/persagy/cameractl/utils/CmdStreamThread.java

@@ -0,0 +1,63 @@
+package com.persagy.cameractl.utils;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+/**
+ * 新线程里读取cmd命令的输入流和错误流以免造成进程堵塞
+ */
+public class CmdStreamThread {
+	private BufferedReader inputBfr = null;
+	private BufferedReader errBfr = null;
+	public String outString;
+	public String errString;
+
+	public CmdStreamThread(InputStream inputStream, InputStream errStream) {
+		this.inputBfr = new BufferedReader(new InputStreamReader(inputStream));
+		this.errBfr = new BufferedReader(new InputStreamReader(errStream));
+		new Thread(new InputStreamThread()).start();
+		new Thread(new ErrStreamThread()).start();
+	}
+
+	/**
+	 * 读取输入流
+	 */
+	class InputStreamThread implements Runnable {
+		@Override
+		public void run() {
+			try {
+				String s;
+				StringBuilder sb = new StringBuilder();
+				while ((s = inputBfr.readLine()) != null) {
+					sb.append(s);
+				}
+				inputBfr.close();
+				outString = sb.toString();
+			} catch (Exception e) {
+				outString = e.getMessage();
+			}
+		}
+	};
+
+	/**
+	 * 读取错误流
+	 */
+	class ErrStreamThread implements Runnable {
+		@Override
+		public void run() {
+			try {
+				String s;
+				StringBuilder sb = new StringBuilder();
+				while ((s = errBfr.readLine()) != null) {
+					sb.append(s);
+				}
+				errBfr.close();
+				errString = sb.toString();
+			} catch (Exception e) {
+				errString = e.getMessage();
+			}
+		}
+	};
+
+}

+ 9 - 0
src/main/java/com/persagy/cameractl/utils/Constants.java

@@ -0,0 +1,9 @@
+package com.persagy.cameractl.utils;
+
+public class Constants {
+
+	public static final String GET_PUBLIC_KEY = "http://{0}:{1}/WPMS/getPublicKey";
+
+	public static final String LOGIN = "http://{0}:{1}/WPMS/login";
+
+}

+ 31 - 0
src/main/java/com/persagy/cameractl/utils/DateUtil.java

@@ -0,0 +1,31 @@
+package com.persagy.cameractl.utils;
+
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+
+public class DateUtil {
+	Instant instant = null;
+
+	public DateUtil(String dateStr) {
+		dateStr = dateStr.replace(' ', 'T');
+		LocalDateTime localDateTime = LocalDateTime.parse(dateStr);
+		ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneId.of("UTC"));
+		instant = zonedDateTime.toInstant();
+	}
+
+	/**
+	 * 获取从公元1970年1月1日0时0分0 秒算起至今的UTC时间所经过的秒数。
+	 */
+	public long getSecondsStart1970UTC() {
+		return instant.getEpochSecond();
+	}
+
+	/**
+	 * 获取从公元1970年1月1日0时0分0 秒算起至今的UTC时间所经过的毫秒数。
+	 */
+	public long getMillSecondsStart1970UTC() {
+		return instant.toEpochMilli();
+	}
+}

+ 63 - 0
src/main/java/com/persagy/cameractl/utils/EnumTools.java

@@ -0,0 +1,63 @@
+package com.persagy.cameractl.utils;
+
+import java.util.ArrayList;
+
+public class EnumTools {
+	/**------------------定义操作系统----------------------*/
+	public enum OperatingSystem {
+		linux, windows, other;
+	}
+
+	/**------------------定义摄像头操作命令类型,SDK的命令,也是浏览器端传过来的命令----------------------*/
+	public static final ArrayList<String> listSdkCommand = new ArrayList<String>() {
+		private static final long serialVersionUID = 1L;
+
+		{
+			// 焦距变大,即倍率变大
+			add("ZOOM_IN");
+			// 焦距变小,即倍率变小
+			add("ZOOM_OUT");
+			// 焦点前调,即调焦++
+			add("FOCUS_NEAR");
+			// 焦点后调,即调焦--
+			add("FOCUS_FAR");
+			// 光圈扩大
+			add("IRIS_OPEN");
+			// 光圈缩小
+			add("IRIS_CLOSE");
+			// 上仰
+			add("TILT_UP");
+			// 下俯
+			add("TILT_DOWN");
+			// 左转
+			add("PAN_LEFT");
+			// 右转
+			add("PAN_RIGHT");
+			// 左上转动或(上仰和左转)
+			add("UP_LEFT");
+			// 左下转动或(下俯和左转)
+			add("DOWN_LEFT");
+			// 右上转动或(上仰和右转)
+			add("UP_RIGHT");
+			// 右下转动或(下俯和右转)
+			add("DOWN_RIGHT");
+		}
+	};
+
+	/**------------------定义摄像头操作命令类型,海康SDK的命令对应的编码----------------------*/
+
+	/**---------------------------------定义摄像头操作命令类型,海康SDK的命令对应的编码-------------------------------------*/
+	public static int[] arrSdkCommandCode = new int[] { 5, 6, 2, 1, 3, 4, 7, 8, 9, 10, 11, 12, 13, 14 };
+
+	/**------------------定义摄像头操作命令类型,海康软件接口的命令----------------------*/
+	public static String[] arrHkvisionCommand = new String[] { "ZOOM_IN", "ZOOM_OUT", "FOCUS_NEAR", "FOCUS_FAR",
+			"IRIS_ENLARGE", "IRIS_REDUCE", "UP", "DOWN", "LEFT", "RIGHT", "LEFT_UP", "LEFT_DOWN", "RIGHT_UP",
+			"RIGHT_DOWN", "" };
+
+	/**------------------定义控制失败编码----------------------*/
+	public enum ControlFailedCode {
+		// 初始化失败
+		init_failed
+	}
+
+}

+ 44 - 0
src/main/java/com/persagy/cameractl/utils/JsonTools.java

@@ -0,0 +1,44 @@
+package com.persagy.cameractl.utils;
+
+import java.io.IOException;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class JsonTools {
+	private static ObjectMapper mapper = new ObjectMapper();
+	
+	public static String obj2Str(Object obj) throws JsonProcessingException {
+		return null != obj ? mapper.writeValueAsString(obj) : null;
+	}
+	
+	public static Map<String, Object> str2Map(String str) throws Exception {
+		if(null == str) {
+			return null;
+		}
+		
+		return mapper.readValue(str, new TypeReference<Map<String, Object>>(){});
+	}
+	
+	public static JsonNode str2JsonNode(String str) throws IOException {
+		if(null != str) {
+			return mapper.readTree(str);
+		}
+		return null;
+	}
+	
+	public static <T> T jsonStr2Obj(String jsonStr, Class<T> clz) throws Exception {
+		if(null == jsonStr) {
+			return null;
+		}
+		
+		return mapper.readValue(jsonStr, clz);
+	}
+	
+	public static JsonNode newInstance() throws IOException {
+		return mapper.readTree("{}");
+	}
+}

+ 24 - 0
src/main/java/com/persagy/cameractl/utils/MimeCamera.java

@@ -0,0 +1,24 @@
+package com.persagy.cameractl.utils;
+
+/**
+ * 大屏的数据源里需要摄像头IP、端口号、通道、用户名、密码,所以单独出类MimeCamera
+ * */
+public class MimeCamera {
+	// 摄像头IP
+	public String cameraIp;
+
+	// 摄像头服务端口号
+	public int cameraPort = 8000;
+
+	// 通道号 1~32表示模拟通道,9000系列混合型DVR和NVR等设备的IP通道从33开始(即程序用的通道号为33+通道号-1)。回放、实时播放、控制使用
+	public int channel;
+
+	// 登录用户名
+	public String userName = "admin";
+
+	// 登录密码
+	public String password;
+
+	// 码流类型 0:主码流 ;	1:子码流 
+	public int streamType = 1;
+}

+ 138 - 0
src/main/java/com/persagy/cameractl/utils/OtherTools.java

@@ -0,0 +1,138 @@
+package com.persagy.cameractl.utils;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import com.persagy.cameractl.utils.EnumTools.OperatingSystem;
+
+import cn.hutool.core.util.StrUtil;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class OtherTools {
+	// 播放mp4文件的url根地址
+	public static String playMp4RootUrl = "/vplayf/";
+	public static String dahuaDllPath = "";
+	public static String fileSperator = File.separator;
+
+	/**
+	 * 获取系统的操作系统类型
+	 */
+	public static OperatingSystem getSystemName() {
+		String os = System.getProperty("os.name").toLowerCase();
+		if (os.indexOf(OperatingSystem.windows.toString()) > -1)
+			return OperatingSystem.windows;
+		else if (os.indexOf(OperatingSystem.linux.toString()) > -1)
+			return OperatingSystem.linux;
+		return OperatingSystem.other;
+	}
+
+	/**
+	 * 获取摄像头厂家dll的路径
+	 */
+	public static String getDllPath(String dllName) {
+		String newPath = "";
+		OperatingSystem systemName = OtherTools.getSystemName();
+		String dllPath = "./config/resourcesFile/cameraDll/" + systemName.toString() + "/" + dllName;
+		try {
+			File file1 = new File(dllPath);
+			newPath = file1.getCanonicalPath();
+		} catch (Exception e) {
+		}
+		return newPath;
+	}
+
+	public static String getLunxDllPath() {
+		String dllPath = "";
+		try {
+			String xiangduiDllPath = "./config/resourcesFile/cameraDll/windows/dssSdk_lunxun/DPSDK_Core";
+			File file1 = new File(xiangduiDllPath);
+			dllPath = file1.getCanonicalPath();
+		} catch (Exception e) {
+			dllPath = "";
+		}
+		return dllPath;
+	};
+
+	/** 操作失败时,拼接错误信息 */
+	public static String joinErrStr(String errCode, String prefix) {
+		return (StrUtil.isBlank(prefix) ? "" : prefix) + (StrUtil.isBlank(errCode) ? "" : ",厂家返回错误码:" + errCode);
+	}
+
+	public static String getVideoFilePath() {
+		String token = StringTools.getUUID();
+		return OtherTools.getVideoFilePathByT(token);
+	};
+
+	public static String getVideoFilePathByT(String token) {
+		try {
+			String playFileName = OtherTools.getMp4FullName(token);
+			String playFileDir = OtherTools.getVideoFileDir();
+			return playFileDir + fileSperator + playFileName;
+		} catch (Exception e) {
+			log.error(e.getMessage());
+			return "";
+		}
+	};
+
+	public static String getVideoFileDir() {
+		String dllPath = "./config/tempVideo";
+		String newPath = "";
+		try {
+			File file1 = new File(dllPath);
+			newPath = file1.getCanonicalPath();
+		} catch (Exception e) {
+		}
+
+		return newPath;
+	}
+
+	public static String getVideoFilePath(Camera _camera) {
+		try {
+			String startTimeStr = _camera.startDateStr.replaceAll("[-:\\s]", "");
+			String endTimeStr = _camera.endDateStr.replaceAll("[-:\\s]", "");
+			String ipStr = _camera.cameraIp.replace(".", "_");
+			String playFileName = OtherTools.getMp4FullName(startTimeStr + "_" + endTimeStr + "_" + _camera.channel);
+			String playFileDir = getVideoFileDir() + fileSperator + ipStr;
+			return playFileDir + fileSperator + playFileName;
+		} catch (Exception e) {
+			log.error(e.getMessage());
+			return "";
+		}
+	};
+
+	public static String getMp4FullName(String prefix) {
+		return prefix + ".mp4";
+	};
+
+	public static String getMp4NamePrefix(String fullName) {
+		return fullName.substring(0, fullName.lastIndexOf("."));
+	};
+
+	public static ResultClass executeErr(String reason) {
+		return new ResultClass(false, reason);
+	};
+
+	public static ResultClass executeSuccess(Object resultData) {
+		return new ResultClass(true, resultData);
+	};
+
+	/**
+	 * 读取标准输入流、输出流,防止进程阻塞
+	 */
+	public static String consumeInputStream(InputStream istream) {
+		try {
+			BufferedReader br = new BufferedReader(new InputStreamReader(istream));
+			String s;
+			StringBuilder sb = new StringBuilder();
+			while ((s = br.readLine()) != null) {
+				sb.append(s);
+			}
+			return sb.toString();
+		} catch (Exception e) {
+			return e.getMessage();
+		}
+	}
+}

+ 25 - 0
src/main/java/com/persagy/cameractl/utils/ResultClass.java

@@ -0,0 +1,25 @@
+package com.persagy.cameractl.utils;
+
+public class ResultClass {
+	public boolean name;
+	public String reason;
+	public Object resultData;
+
+	public ResultClass() {
+	};
+
+	public ResultClass(boolean _name, String _reason) {
+		this(_name, _reason, null);
+	};
+
+	public ResultClass(boolean _name, Object _resultData) {
+		this(_name, "", _resultData);
+	};
+
+	public ResultClass(boolean _name, String _reason, Object _resultData) {
+		this.name = _name;
+		this.reason = _reason;
+		this.resultData = _resultData;
+	};
+
+}

+ 71 - 0
src/main/java/com/persagy/cameractl/utils/ResultTools.java

@@ -0,0 +1,71 @@
+package com.persagy.cameractl.utils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+
+public class ResultTools {
+	public static final String err_param_not_found = "缺少必填参数";
+	public static final String err_param_time_limit = "时间超过限制";
+	public static final String err_param_format = "参数格式错误";
+	public static final String err_param_obj_id = "未找到指定id对象";
+	public static final String err_param_value_illegal = "参数值不合法:";
+	public static final String err_service = "服务错误:";
+	public static final String err_crud_save = "保存失败:";
+	public static final String err_crud_update = "更新失败:";
+	public static final String err_crud_delete = "删除失败:";
+	public static final String err_crud_query = "查询失败:";
+	public static final String result_success = "success";
+	public static final String result_failure = "failure";
+	public static final String key_result = "result";
+	public static final String key_err_message = "reason";
+	public static final String key_data = "data";
+	
+	public static String errorResult(String errorMsg) {
+		Map<String, Object> map = getDataResult();
+		map.put(key_result, result_failure);
+		map.put(key_err_message, errorMsg);
+		return map2str(map);
+	}
+	
+	public static String illegalParamResult(String param) {
+		Map<String, Object> map = getDataResult();
+		map.put(key_result, result_failure);
+		map.put(key_err_message, "param "+param+" is illegal");
+		return map2str(map);
+	}
+	
+	public static String successResult() {
+		return map2str(getDataResult());
+	}
+	
+	public static String successResult(String message) {
+		Map<String, Object> map = getDataResult();
+		map.put(key_err_message, message);
+		return map2str(map);
+	}
+	
+	public static String dataResult(Object data) {
+		Map<String, Object> map = getDataResult();
+		map.put(key_data, data);
+		return map2str(map);
+	}
+	
+	private static Map<String, Object> getDataResult() {
+		Map<String, Object> map = new HashMap<>();
+		map.put(key_result, result_success);
+		return map;
+	}
+	
+	private static String map2str(Map<String, Object> map) {
+		String result  = "{}";
+		try {
+			result = JsonTools.obj2Str(map);
+		} catch (JsonProcessingException e) {
+			e.printStackTrace();
+		}
+		return result;
+	}
+	
+}

+ 311 - 0
src/main/java/com/persagy/cameractl/utils/StringTools.java

@@ -0,0 +1,311 @@
+package com.persagy.cameractl.utils;
+
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public final class StringTools {
+
+	/**
+	 * 获取UUID字符串
+	 * 
+	 * @param length 指定字符长度,范围(0,36],若为null则视length=36处理
+	 * @return 固定长度的数字+小写字母+中划线组合的UUID字符串
+	 */
+	public static String getUUID(Integer length) {
+		String uuidStr = UUID.randomUUID().toString();
+		if (null != length) {
+			length = length > 36 ? 36 : length;
+			uuidStr = uuidStr.substring(0, length);
+		}
+		return uuidStr;
+	}
+
+	/**
+	 * 获取32位长度UUID
+	 * 
+	 * @return 32长度,只包含数字+小写字母
+	 */
+	public static String getUUID() {
+		return getUUID(36).replace("-", "");
+	}
+
+	public static void main(String[] args) {
+		System.out.println(getUUID());
+	}
+
+	/**
+	 * 获取字符串str对应的hash散列结果值
+	 * 
+	 * @param str
+	 * @return 000-999之间的数字字符串
+	 */
+	public static String getHashNum(String str) {
+		str = str == null ? "" : str;
+
+		// 得到哈希正整数
+		int hashInt = Math.abs(str.hashCode());
+
+		// 设置哈希字符值,长度为4位
+		hashInt = 100000 + hashInt % 1000;
+		String hashStr = ("" + hashInt).substring(3);
+
+		return hashStr;
+	}
+
+	/**
+	 * 提供空字符串.
+	 */
+	public static final java.lang.String EMPTY = "";
+
+	/**
+	 * 判断字符串是否为null,或者是空串"", 或者是空格串" "
+	 * 
+	 * @param str
+	 * @return boolean
+	 */
+	public static boolean isBlank(String str) {
+		if (isEmpty(str)) {
+			return true;
+		}
+
+		return str.trim().length() == 0;
+	}
+
+	/**
+	 * 如果源字符串str为null,空串或空格串则返回默认字符串
+	 * 
+	 * @param str    源字符串
+	 * @param defStr 默认字符串
+	 * @return String
+	 */
+	public static String getDefault(String str, String defStr) {
+		return isBlank(str) ? defStr : str;
+	}
+
+	/**
+	 * 判断字符串是否为null,或者是空串"" .
+	 * 
+	 * @param s
+	 * @return boolean
+	 */
+	public static boolean isEmpty(String s) {
+		return (s == null || s.length() == 0);
+	}
+
+	/**
+	 * 判断字符串是否不为null,且不是空串"" .
+	 * 
+	 * @param s
+	 * @return boolean
+	 */
+	public static boolean isNotEmpty(String s) {
+		return !isEmpty(s);
+	}
+
+	public static final String toString(Object o) {
+		return o != null ? o.toString() : null;
+	}
+
+	/**
+	 * 判断是否为空格字符串 .
+	 * 
+	 * @param cs
+	 * @return boolean
+	 */
+	public static boolean isBlank(CharSequence cs) {
+		if (null == cs)
+			return false;
+		int length = cs.length();
+		for (int i = 0; i < length; i++) {
+			if (!Character.isWhitespace(cs.charAt(i)))
+				return false;
+		}
+		return true;
+	}
+
+	/**
+	 * 比较字符串是否相等,都为null时,返回true .
+	 * 
+	 * @param string1
+	 * @param string2
+	 * @return boolean
+	 */
+	public static boolean equalsWithNull(String string1, String string2) {
+		if (string1 == null) {
+			if (string2 == null) {
+				return true;
+			} else {
+				return false;
+			}
+		} else {
+			return string1.equals(string2);
+		}
+	}
+
+	public static boolean checkIsPhone(String phonenumber) {
+		String phone = "(^(d{3,4}-)?d{7,8})$|(1[0-9]{10})";
+		String tregEx = "[0-9]{7,8}"; // 表示a或f 0832-80691990
+		Pattern p = Pattern.compile(phone);
+		Matcher m = p.matcher(phonenumber);
+		Pattern p2 = Pattern.compile(tregEx);
+		Matcher m2 = p2.matcher(phonenumber);
+		// String regEx="[1]{1}[3,5,8,6]{1}[0-9]{9}"; //手机
+		// String tregEx="[0]{1}[0-9]{2,3}-[0-9]{7,8}"; //表示a或f 0832-80691990
+		return m.matches() || m2.matches();
+	}
+
+	/**
+	 * 判断字符串中是否包含汉字,如字符串为空,返回false .
+	 * 
+	 * @param str
+	 * @return boolean
+	 */
+	public static boolean hasHanZi(String str) {
+		if (StringTools.isEmpty(str)) {
+			return false;
+		}
+		String regEx = "[\\u4e00-\\u9fa5]";
+
+		Pattern pat = Pattern.compile(regEx);
+		Matcher mat = pat.matcher(str);
+		return mat.find();
+
+	}
+
+	/**
+	 * 去除非汉字内容
+	 */
+	public static String clearNotChinese(String buff) {
+		String tmpString = buff.replaceAll("(?i)[^a-zA-Z0-9\u4E00-\u9FA5]", "");// 去掉所有中英文符号
+		char[] carr = tmpString.toCharArray();
+		for (int i = 0; i < tmpString.length(); i++) {
+			if (carr[i] < 0xFF) {
+				carr[i] = ' ';// 过滤掉非汉字内容
+			}
+		}
+		return String.copyValueOf(carr).trim();
+	}
+
+	/**
+	 * 字符串中的数字转为*
+	 * 
+	 * @param str
+	 * @return String
+	 */
+	public static String spriceNumberic(String str) {
+		StringBuffer sb = new StringBuffer();
+		if (str != null) {
+			for (int i = 0; i < str.length(); i++) {
+				if (Character.isDigit(str.charAt(i))) {
+					sb.append("*");
+				} else {
+					sb.append(str.charAt(i));
+				}
+			}
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * 去除字符里包含的回车(\n)、水平制表符(\t)、空格(\s)、换行(\r) .
+	 * 
+	 * @param str
+	 * @return String
+	 */
+	public static String replaceSpecilSign(String str) {
+		String dest = "";
+		if (isNotEmpty(str)) {
+			Pattern p = Pattern.compile("\\s*|\t|\r|\n");
+
+			Matcher m = p.matcher(str);
+
+			dest = m.replaceAll("");
+		}
+		return dest;
+	}
+
+	/**
+	 * 判断一个字符串是否为数字型字符串 .
+	 * 
+	 * @param str
+	 * @return boolean
+	 */
+	public static boolean isNumberic(String str) {
+		if (isEmpty(str)) {
+			return false;
+		}
+		Pattern pattern = Pattern.compile("[0-9]*");
+		return pattern.matcher(str).matches();
+	}
+
+	/**
+	 * 目标字符是否包含正则表达式所给字符 .
+	 * 
+	 * @param destStr 目标字符
+	 * @param regEx   正则表达式
+	 * @return boolean
+	 */
+	public static boolean containString(String destStr, String regEx) {
+		if (isEmpty(destStr)) {
+			return false;
+		}
+		if (isEmpty(regEx)) {
+			return false;
+		}
+		Pattern p = Pattern.compile(regEx);
+		Matcher m = p.matcher(destStr);
+		return m.find();
+	}
+
+	/**
+	 * Description: 判断字符串是否为合法的文件名(不包含后缀).
+	 * 
+	 * @param fileName
+	 * @return boolean
+	 */
+	public static boolean isFileName(String fileName) {
+		if (fileName == null || fileName.length() > 255) {
+			return false;
+		} else if (isBlank(fileName)) {
+			return true;
+		} else {
+			return fileName.matches(
+					"[^\\s\\\\/:\\*\\?\\\"<>\\|](\\x20|[^\\s\\\\/:\\*\\?\\\"<>\\|])*[^\\s\\\\/:\\*\\?\\\"<>\\|\\.]$");
+		}
+	}
+
+	/**
+	 * 将字符串首字母大写 .
+	 * 
+	 * @param s
+	 * @return String
+	 */
+	public static String capitalize(CharSequence s) {
+		if (null == s)
+			return null;
+		int len = s.length();
+		if (len == 0)
+			return "";
+		char char0 = s.charAt(0);
+		if (Character.isUpperCase(char0))
+			return s.toString();
+		return new StringBuilder(len).append(Character.toUpperCase(char0)).append(s.subSequence(1, len)).toString();
+	}
+
+	/**
+	 * 判断String是否为null或空
+	 * 
+	 * @param params
+	 * @return
+	 */
+	public static boolean isNull(String... params) {
+		for (String param : params) {
+			if (param == null || "".equals(param)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+}

+ 44 - 0
src/main/java/com/persagy/cameractl/utils/TimerInterval.java

@@ -0,0 +1,44 @@
+package com.persagy.cameractl.utils;
+
+import java.io.File;
+import java.util.Timer;
+
+/**
+ * 定时程序,目前包括:定时清除生成的mp4文件
+ * 
+ * @author zhangqiankun
+ */
+public class TimerInterval {
+
+	public static void startClearFileTimer() {
+		Timer fileClearTimer = new Timer();
+		// 0秒后开始响应函数,每隔五分钟执行一次
+		fileClearTimer.schedule(new ClearTileTimer(), 0, 1000 * 60 * 20);
+	};
+
+}
+
+class ClearTileTimer extends java.util.TimerTask {
+	
+	@Override
+	public void run() {
+		String dirString = OtherTools.getVideoFileDir();
+		File dir = new File(dirString);
+		if (!dir.exists() || !dir.isDirectory()) {// 判断是否存在目录
+			return;
+		}
+		// 五分钟
+		long timeP = 1000 * 60 * 5;
+		long currTime = System.currentTimeMillis();
+		String[] files = dir.list();			// 读取目录下的所有目录文件信息
+		for (int i = 0; i < files.length; i++) {// 循环,添加文件名或回调自身
+			File file = new File(dir, files[i]);
+			long lastModTime = file.lastModified();
+			// 5分钟以上的文件清除
+			if (currTime - lastModTime > timeP) {
+				file.delete();
+			}
+		}
+	}
+	
+}

+ 55 - 0
src/main/java/com/persagy/nvr/DataPlayCallBackClass.java

@@ -0,0 +1,55 @@
+package com.persagy.nvr;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.sun.jna.Pointer;
+import com.sun.jna.platform.win32.WinDef.LPVOID;
+import com.sun.jna.platform.win32.WinDef.UINT;
+
+public class DataPlayCallBackClass implements VskClient.DataPlayCallBack {
+	Logger logger = LoggerFactory.getLogger(DataPlayCallBackClass.class);
+	// interface DataPlayCallBack extends Callback {
+	// void Callback(WinDef.UINT PlayHandle, WinDef.UINT DateType, byte[] pBuffer,
+	// WinDef.UINT BufferSize, WinDef.LPVOID pUser);
+	// }
+	@Override
+	public void Callback(UINT PlayHandle, int DateType, Pointer pBuffer, int BufferSize, LPVOID pUser) {
+		// byte[] byteArr = pBuffer.getByteArray(0, BufferSize);
+		// backByteBufferList.add(byteArr);
+
+		logger.error("数据回调,byteArr。length:" + BufferSize + ",DateType:" + DateType+",线程ID:"+Thread.currentThread().getId());
+		switch (DateType) {
+		case 0:
+			logger.error("********************************************系统头");
+			break;
+		case 2:
+			logger.error("********************************************最后");
+			break;
+		default:
+			break;
+		}
+
+		if(pBuffer!=null) {
+			long size=Pointer.nativeValue(pBuffer);
+			pBuffer.clear(size);
+		}
+		if(pUser!=null) {
+			Pointer puser=pUser.getPointer();
+			long size2=Pointer.nativeValue(puser);
+			puser.clear(size2);
+		}
+
+		// try {
+		// RandomAccessFile randomFile = new
+		// RandomAccessFile("./config/tempVideo/a.mp4", "rw");
+		// long fileLength = randomFile.length();
+		// // 将写文件指针移到文件尾
+		// randomFile.seek(fileLength);
+		// randomFile.write(byteArr);
+		// randomFile.close();
+		// } catch (Exception e) {
+		// logger.error("byteArr写入异常:",e);
+		// }
+	};
+}

+ 86 - 0
src/main/java/com/persagy/nvr/EndPlayCallBackClass.java

@@ -0,0 +1,86 @@
+package com.persagy.nvr;
+
+import java.io.File;
+import java.io.FileOutputStream;
+
+import com.persagy.cameractl.conf.AllStaticConfig;
+import com.persagy.cameractl.utils.OtherTools;
+import com.sun.jna.Pointer;
+import com.sun.jna.platform.win32.WinDef;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class EndPlayCallBackClass implements VskClient.PlayBackEndCallBack {
+
+	@Override
+	public void Callback(WinDef.UINT pbhandle, int errorcode, Pointer puser) {
+		log.info("回放结束");
+		if (errorcode == 0) {
+			// 根据SDK的PS流生成的MP4文件
+			String sourceToken = OtherTools.getMp4NamePrefix("_" + AllStaticConfig.playBackFileName);
+			// 播放结束了,生成源mp4文件
+			String sourceFilePath = OtherTools.getVideoFilePathByT(sourceToken);
+			try {
+				File sourceFile = new File(sourceFilePath);
+				sourceFile.createNewFile();// 有路径才能创建文件
+
+				// 生成源MP4
+				byte[] dataByteArr = new byte[0];
+				int listSize = AllStaticConfig.backByteBufferList.size();
+
+				for (int i = 0; i < listSize; i++) {
+					byte[] currByteArr = AllStaticConfig.backByteBufferList.get(i);
+					byte[] tempArr = new byte[dataByteArr.length + currByteArr.length];
+					// 参数依次为:源数组、从其开始复制的源数组索引、目标数组、开始放入数据的目标数组索引、要复制的元素数
+					System.arraycopy(dataByteArr, 0, tempArr, 0, dataByteArr.length);
+					System.arraycopy(currByteArr, 0, tempArr, dataByteArr.length, currByteArr.length);
+					dataByteArr = tempArr;
+				}
+
+				FileOutputStream fos = new FileOutputStream(sourceFile);
+				fos.write(dataByteArr);
+				fos.close();
+
+				// 把源MP4转为页面上可播放的MP4
+				Runtime run = Runtime.getRuntime();
+				Process p = run.exec(
+						"ffmpeg -i \"" + sourceFilePath + "\" -c copy -y \"" + AllStaticConfig.playBackFilePath + "\"");
+				// 释放进程
+				// p.getOutputStream().close();
+				// p.getInputStream().close();
+				// p.getErrorStream().close();
+
+				// 读取标准输入流、输出流,防止进程阻塞
+				// 标准输入流(必须写在 waitFor 之前)
+				String inputStreamStr = OtherTools.consumeInputStream(p.getInputStream());
+				// 标准错误流(必须写在 waitFor 之前)
+				String errStreamStr = OtherTools.consumeInputStream(p.getErrorStream());
+
+				int retCode = p.waitFor();
+				if (retCode == 0) {
+					AllStaticConfig.backByteBufferList.clear();
+					// 正常转换结束
+					AllStaticConfig.playBackMp4State = 1;
+				} else {
+					// 转换出错
+					String errStr = errStreamStr != null ? errStreamStr : inputStreamStr;
+					log.error("ffmpeg转换mp4时失败,错误信息:" + errStr);
+					AllStaticConfig.backByteBufferList.clear();
+					AllStaticConfig.playBackMp4State = 2;
+				}
+				p.destroy();
+				sourceFile.delete();
+			} catch (Exception e) {
+				log.error("生成回放mp4时异常:", e);
+				AllStaticConfig.backByteBufferList.clear();
+				AllStaticConfig.playBackMp4State = 2;
+			}
+		} else {
+			log.error("回放结束时错误,错误码::" + errorcode);
+			AllStaticConfig.backByteBufferList.clear();
+			AllStaticConfig.playBackMp4State = 2;
+		}
+	};
+	
+}

+ 38 - 0
src/main/java/com/persagy/nvr/FNVR_SYS_INFO.java

@@ -0,0 +1,38 @@
+package com.persagy.nvr;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+import com.sun.jna.platform.win32.WinDef;
+
+public class FNVR_SYS_INFO extends Structure {
+    public byte video_chns;
+    public byte audio_chns;
+    public byte alarmin_chns;
+    public byte alarmout_chns;
+    public byte serial_num;
+    public byte dec_pic_size;
+    public WinDef.USHORT vga_resolution;
+    public WinDef.UINT version;
+    public byte[] reserved = new byte[12];
+    public byte[] release_date = new byte[32];
+
+    public static class ByReference extends FNVR_SYS_INFO implements Structure.ByReference {}
+    public static class ByValue extends FNVR_SYS_INFO implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+
+        return Arrays.asList("video_chns",
+                "audio_chns",
+                "alarmin_chns",
+                "alarmout_chns",
+                "serial_num",
+                "dec_pic_size",
+                "vga_resolution",
+                "version",
+                "reserved",
+                "release_date");
+    }
+}

+ 19 - 0
src/main/java/com/persagy/nvr/FNVR_SYS_INFO_DSP.java

@@ -0,0 +1,19 @@
+package com.persagy.nvr;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+import com.sun.jna.platform.win32.WinDef;
+
+public class FNVR_SYS_INFO_DSP extends Structure {
+    public WinDef.UINT dspversion;
+
+    public static class ByReference extends FNVR_SYS_INFO_DSP implements Structure.ByReference {}
+    public static class ByValue extends FNVR_SYS_INFO_DSP implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("dspversion");
+    }
+}

+ 140 - 0
src/main/java/com/persagy/nvr/GlobalExceptionHandler.java

@@ -0,0 +1,140 @@
+package com.persagy.nvr;
+
+import java.io.IOException;
+
+import org.springframework.beans.ConversionNotSupportedException;
+import org.springframework.http.converter.HttpMessageNotReadableException;
+import org.springframework.http.converter.HttpMessageNotWritableException;
+import org.springframework.web.HttpMediaTypeNotAcceptableException;
+import org.springframework.web.HttpRequestMethodNotSupportedException;
+import org.springframework.web.bind.MissingServletRequestParameterException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import com.sun.corba.se.impl.io.TypeMismatchException;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RestControllerAdvice
+@SuppressWarnings("restriction")
+public class GlobalExceptionHandler {
+	
+	private static final String logExceptionFormat = "Capture Exception By GlobalExceptionHandler: Code: %s Detail: %s";
+
+    //运行时异常
+    @ExceptionHandler(RuntimeException.class)
+    public String runtimeExceptionHandler(RuntimeException ex) {
+        log.error(resultFormat(1, ex));
+        return resultFormat(1, ex);
+    }
+
+    //空指针异常
+    @ExceptionHandler(NullPointerException.class)
+    public String nullPointerExceptionHandler(NullPointerException ex) {
+        log.error(resultFormat(2, ex));
+        return resultFormat(2, ex);
+    }
+
+    //类型转换异常
+    @ExceptionHandler(ClassCastException.class)
+    public String classCastExceptionHandler(ClassCastException ex) {
+        log.error(resultFormat(3, ex));
+        return resultFormat(3, ex);
+    }
+
+    //IO异常
+    @ExceptionHandler(IOException.class)
+    public String iOExceptionHandler(IOException ex) {
+        log.error(resultFormat(4, ex));
+        return resultFormat(4, ex);
+    }
+
+    //未知方法异常
+    @ExceptionHandler(NoSuchMethodException.class)
+    public String noSuchMethodExceptionHandler(NoSuchMethodException ex) {
+        log.error(resultFormat(5, ex));
+        return resultFormat(5, ex);
+    }
+
+    //数组越界异常
+    @ExceptionHandler(IndexOutOfBoundsException.class)
+    public String indexOutOfBoundsExceptionHandler(IndexOutOfBoundsException ex) {
+        log.error(resultFormat(6, ex));
+        return resultFormat(6, ex);
+    }
+
+    //400错误
+    @ExceptionHandler({HttpMessageNotReadableException.class})
+    public String requestNotReadable(HttpMessageNotReadableException ex) {
+        log.error(resultFormat(7, ex));
+        System.out.println("400..requestNotReadable");
+        return resultFormat(7, ex);
+    }
+
+    //400错误
+	@ExceptionHandler({TypeMismatchException.class})
+    public String requestTypeMismatch(TypeMismatchException ex) {
+        log.error(resultFormat(8, ex));
+        return resultFormat(8, ex);
+    }
+
+    //400错误
+    @ExceptionHandler({MissingServletRequestParameterException.class})
+    public String requestMissingServletRequest(MissingServletRequestParameterException ex) {
+        log.error(resultFormat(9, ex));
+        return resultFormat(9, ex);
+    }
+
+    //405错误
+    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
+    public String request405(HttpRequestMethodNotSupportedException ex) {
+        log.error(resultFormat(10, ex));
+        return resultFormat(10, ex);
+    }
+
+    //406错误
+    @ExceptionHandler({HttpMediaTypeNotAcceptableException.class})
+    public String request406(HttpMediaTypeNotAcceptableException ex) {
+        log.error(resultFormat(11, ex));
+        System.out.println("406...");
+        return resultFormat(11, ex);
+    }
+
+    //500错误
+    @ExceptionHandler({ConversionNotSupportedException.class, HttpMessageNotWritableException.class})
+    public String server500(RuntimeException ex) {
+        log.error(resultFormat(12, ex));
+        System.out.println("500...");
+        return resultFormat(12, ex);
+    }
+
+    //栈溢出
+    @ExceptionHandler({StackOverflowError.class})
+    public String requestStackOverflow(StackOverflowError ex) {
+        log.error(resultFormat(13, ex));
+        return resultFormat(13, ex);
+    }
+
+    //除数不能为0
+    @ExceptionHandler({ArithmeticException.class})
+    public String arithmeticException(ArithmeticException ex) {
+        log.error(resultFormat(13, ex));
+        return resultFormat(13, ex);
+    }
+
+
+    //其他错误
+    @ExceptionHandler({Exception.class})
+    public String exception(Exception ex) {
+        log.error(resultFormat(14, ex));
+        return resultFormat(14, ex);
+    }
+
+    private <T extends Throwable> String resultFormat(Integer code, T ex) {
+        log.error(String.format(logExceptionFormat, code, ex.getMessage()));
+        return code+":"+ ex.getMessage();
+    }
+
+	    
+}

+ 60 - 0
src/main/java/com/persagy/nvr/JavaStructBase.java

@@ -0,0 +1,60 @@
+package com.persagy.nvr;
+
+import java.lang.reflect.Field;
+import java.util.LinkedList;
+import java.util.List;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+
+/** * java struct base * * @author fanpei * */
+public abstract class JavaStructBase extends Structure {
+	/** * 默认构造函数 */
+	public JavaStructBase() {
+	}
+
+	/** * 构造函数 * * @param _pointer */
+	public JavaStructBase(Pointer _pointer) {
+		super(_pointer);
+	}
+
+	/** * 结构体的引用 * * @author maoko * */
+	public static class ByReference extends JavaStructBase implements Structure.ByReference {
+	}
+
+	/** * 结构体对象 * * @author fanpei * */
+	public static class ByValue extends JavaStructBase implements Structure.ByValue {
+	}
+
+	@Override
+	protected List<String> getFieldOrder() {
+		return getStructFields();
+	}
+
+	/** * 自定义反射获取字段顺序 * * @return */
+	private List<String> getStructFields() {
+		List<String> feilds = new LinkedList<>();
+		Field[] declearedFeilds = this.getClass().getDeclaredFields();
+		if (declearedFeilds != null && declearedFeilds.length > 0) {
+			for (Field f : declearedFeilds) {
+				feilds.add(f.getName());
+			}
+		}
+		return feilds;
+	}
+
+	/** * 打印字段-测试用 */
+	@Deprecated
+	public void printStructFeilds() {
+		List<String> feilds = getStructFields();
+		if (feilds == null || feilds.size() == 0)
+			System.out.println("feilds:none");
+		else {
+			StringBuilder feidlSb = new StringBuilder("feilds:");
+			for (String f : feilds) {
+				feidlSb.append(f);
+				feidlSb.append(",");
+			}
+			System.out.println(feidlSb.toString());
+		}
+	}
+}

+ 50 - 0
src/main/java/com/persagy/nvr/MCAST_DEVICE_PACKET_EX.java

@@ -0,0 +1,50 @@
+package com.persagy.nvr;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+import com.sun.jna.platform.win32.WinDef;
+
+public class MCAST_DEVICE_PACKET_EX extends Structure {
+    public WinDef.UINT version;
+    public WinDef.UINT cmd;
+    public WinDef.UINT session;
+    public WinDef.UINT deviceip;
+    public WinDef.UINT deviceport;
+    public WinDef.UINT devicemask;
+    public WinDef.UINT devicegate;
+    public byte[] macaddr = new byte[8];
+    public WinDef.UINT machtype;
+    public FNVR_SYS_INFO systeminfo;
+    public FNVR_SYS_INFO_DSP dspinfo;
+    public WinDef.UINT httpport;
+    public byte[] hardwaremodel = new byte[16];
+    public WinDef.UINT bdevicemodel;
+    public byte[] resev = new byte[40];
+    public byte[] devcemodelstr = new byte[64];
+
+
+    public static class ByReference extends MCAST_DEVICE_PACKET_EX implements Structure.ByReference {}
+    public static class ByValue extends MCAST_DEVICE_PACKET_EX implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("version",
+                "cmd",
+                "session",
+                "deviceip",
+                "deviceport",
+                "devicemask",
+                "devicegate",
+                "macaddr",
+                "machtype",
+                "systeminfo",
+                "dspinfo",
+                "httpport",
+                "hardwaremodel",
+                "bdevicemodel",
+                "resev",
+                "devcemodelstr");
+    }
+}

+ 38 - 0
src/main/java/com/persagy/nvr/NvrTest.java

@@ -0,0 +1,38 @@
+package com.persagy.nvr;
+
+//import com.persagy.vx.models.DeviceInfo;
+//import com.persagy.vx.models.StatusNotify;
+//import com.sun.jna.Library;
+//import com.sun.jna.Native;
+//import com.sun.jna.Pointer;
+//import com.sun.jna.WString;
+
+public class NvrTest {
+
+    public static void main(String[] args) {
+//    	String SERVER_ROOT_PATH = System.getProperty("user.dir");
+//        System.load(SERVER_ROOT_PATH + "/config/lib/libcares.dll");
+//        System.load("E:\\Persagy\\source\\iot\\Vx\\VxTest\\lib\\liblame.dll");
+//        System.load("E:\\Persagy\\source\\iot\\Vx\\VxTest\\lib\\libmad.dll");
+//        System.load("E:\\Persagy\\source\\iot\\Vx\\VxTest\\lib\\libresample.dll");
+//        System.load("E:\\Persagy\\source\\iot\\Vx\\VxTest\\lib\\libwebrtc.dll");
+//        System.load("E:\\Persagy\\source\\iot\\Vx\\VxTest\\lib\\ortp.dll");
+//        System.load("E:\\Persagy\\source\\iot\\Vx\\VxTest\\lib\\osipparser2.dll");
+//        System.load("E:\\Persagy\\source\\iot\\Vx\\VxTest\\lib\\portaudio_x86.dll");
+//        System.load("E:\\Persagy\\source\\iot\\Vx\\VxTest\\lib\\osip2.dll");
+//        System.load("E:\\Persagy\\source\\iot\\Vx\\VxTest\\lib\\eXosip.dll");
+//        System.load("E:\\Persagy\\source\\iot\\Vx\\VxTest\\lib\\XC9000UA.dll");
+    }
+
+    public static String bytesToString(byte[] bstr, String charset) throws Exception {
+        int len = 0;
+        for (len = 0; len < bstr.length; len++) {
+            if (0 == bstr[len]) {
+                break;
+            }
+        }
+        byte[] buf = new byte[len];
+        System.arraycopy(bstr, 0, buf, 0, len);
+        return new String(buf, charset);
+    }
+}

+ 281 - 0
src/main/java/com/persagy/nvr/SdkMapper.java

@@ -0,0 +1,281 @@
+package com.persagy.nvr;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+
+import com.sun.jna.FunctionMapper;
+import com.sun.jna.NativeLibrary;
+
+public class SdkMapper implements FunctionMapper {
+	
+    /** 保存函数名映射关系 */
+    HashMap<String, String> map = new HashMap<String, String>();
+
+    /**
+     * 构造函数
+     */
+    public SdkMapper() {
+        /** 在此填写函数名映射关系 */
+        map.put("JsonSdk_AddAIUserInfo", "_JsonSdk_AddAIUserInfo@8");
+        map.put("JsonSdk_AddIPC", "_JsonSdk_AddIPC@8");
+        map.put("JsonSdk_AddUserGroupInfo", "_JsonSdk_AddUserGroupInfo@8");
+        map.put("JsonSdk_AddUserInfo", "_JsonSdk_AddUserInfo@8");
+        map.put("JsonSdk_AiUserPicUpload", "_JsonSdk_AiUserPicUpload@16");
+        map.put("JsonSdk_ChannelConfigExport", "_JsonSdk_ChannelConfigExport@16");
+        map.put("JsonSdk_ChannelConfigImport", "_JsonSdk_ChannelConfigImport@12");
+        map.put("JsonSdk_Clear", "_JsonSdk_Clear@0");
+        map.put("JsonSdk_ClearIpcStreamTransPort", "_JsonSdk_ClearIpcStreamTransPort@4");
+        map.put("JsonSdk_ClearOnlineUser", "_JsonSdk_ClearOnlineUser@8");
+        map.put("JsonSdk_ConfigExport", "_JsonSdk_ConfigExport@16");
+        map.put("JsonSdk_ConfigImport", "_JsonSdk_ConfigImport@8");
+        map.put("JsonSdk_ConvertToHotDisk", "_JsonSdk_ConvertToHotDisk@8");
+        map.put("JsonSdk_CreateRaidLogicalDisk", "_JsonSdk_CreateRaidLogicalDisk@8");
+        map.put("JsonSdk_DelAIUserInfo", "_JsonSdk_DelAIUserInfo@8");
+        map.put("JsonSdk_DelAiUserPicInfo", "_JsonSdk_DelAiUserPicInfo@8");
+        map.put("JsonSdk_DelReverseLinkProxedInfo", "_JsonSdk_DelReverseLinkProxedInfo@8");
+        map.put("JsonSdk_DeleteNvrBackup", "_JsonSdk_DeleteNvrBackup@8");
+        map.put("JsonSdk_DeleteRaidLogicalDisk", "_JsonSdk_DeleteRaidLogicalDisk@8");
+        map.put("JsonSdk_DeleteUserGroupInfo", "_JsonSdk_DeleteUserGroupInfo@8");
+        map.put("JsonSdk_DeleteUserInfo", "_JsonSdk_DeleteUserInfo@8");
+        map.put("JsonSdk_DownloadCtrl", "_JsonSdk_DownloadCtrl@8");
+        map.put("JsonSdk_DownloadGetPos", "_JsonSdk_DownloadGetPos@4");
+        map.put("JsonSdk_DownloadSmallFile", "_JsonSdk_DownloadSmallFile@16");
+        map.put("JsonSdk_DownloadStart", "_JsonSdk_DownloadStart@32");
+        map.put("JsonSdk_DownloadStartByTime", "_JsonSdk_DownloadStartByTime@36");
+        map.put("JsonSdk_DownloadStop", "_JsonSdk_DownloadStop@4");
+        map.put("JsonSdk_ExceptionCallBack", "_JsonSdk_ExceptionCallBack@20");
+        map.put("JsonSdk_ExportAIUserInfo", "_JsonSdk_ExportAIUserInfo@12");
+        map.put("JsonSdk_FileLock", "_JsonSdk_FileLock@8");
+        map.put("JsonSdk_FileUnlock", "_JsonSdk_FileUnlock@8");
+        map.put("JsonSdk_FormatDiskByDiskNo", "_JsonSdk_FormatDiskByDiskNo@8");
+        map.put("JsonSdk_FreeBuffer", "_JsonSdk_FreeBuffer@4");
+        map.put("JsonSdk_FreeDataLink", "_JsonSdk_FreeDataLink@4");
+        map.put("JsonSdk_GetAIUserInfoList", "_JsonSdk_GetAIUserInfoList@16");
+        map.put("JsonSdk_GetAlarmInDetectParam", "_JsonSdk_GetAlarmInDetectParam@20");
+        map.put("JsonSdk_GetAllRecordState", "_JsonSdk_GetAllRecordState@12");
+        map.put("JsonSdk_GetCameraAlarmDetectParam", "_JsonSdk_GetCameraAlarmDetectParam@20");
+        map.put("JsonSdk_GetCruiseParam", "_JsonSdk_GetCruiseParam@16");
+        map.put("JsonSdk_GetDiskGroupChannelParam", "_JsonSdk_GetDiskGroupChannelParam@16");
+        map.put("JsonSdk_GetDiskGroupParam", "_JsonSdk_GetDiskGroupParam@16");
+        map.put("JsonSdk_GetDiskInfo", "_JsonSdk_GetDiskInfo@12");
+        map.put("JsonSdk_GetErrMsg", "_JsonSdk_GetErrMsg@12");
+        map.put("JsonSdk_GetExceptionDetectParam", "_JsonSdk_GetExceptionDetectParam@16");
+        map.put("JsonSdk_GetFacePictureAlarmConfig", "_JsonSdk_GetFacePictureAlarmConfig@12");
+        map.put("JsonSdk_GetFacePictureAlarmConfigByChinID", "_JsonSdk_GetFacePictureAlarmConfigByChinID@16");
+        map.put("JsonSdk_GetFacePictureBaseConfig", "_JsonSdk_GetFacePictureBaseConfig@12");
+        map.put("JsonSdk_GetFormatDiskPrecentByDiskNo", "_JsonSdk_GetFormatDiskPrecentByDiskNo@12");
+        map.put("JsonSdk_GetNVRConfig", "_JsonSdk_GetNVRConfig@24");
+        map.put("JsonSdk_GetNVRTime", "_JsonSdk_GetNVRTime@8");
+        map.put("JsonSdk_GetNvrAlarmCenterParam", "_JsonSdk_GetNvrAlarmCenterParam@16");
+        map.put("JsonSdk_GetNvrAlarmConfig", "_JsonSdk_GetNvrAlarmConfig@12");
+        map.put("JsonSdk_GetNvrAlarmOutDetectConfig", "_JsonSdk_GetNvrAlarmOutDetectConfig@20");
+        map.put("JsonSdk_GetNvrAlarmOutStatus", "_JsonSdk_GetNvrAlarmOutStatus@12");
+        map.put("JsonSdk_GetNvrAlarmOutStrategy", "_JsonSdk_GetNvrAlarmOutStrategy@16");
+        map.put("JsonSdk_GetNvrBackupList", "_JsonSdk_GetNvrBackupList@12");
+        map.put("JsonSdk_GetNvrCapabilities", "_JsonSdk_GetNvrCapabilities@12");
+        map.put("JsonSdk_GetNvrCommonConfig", "_JsonSdk_GetNvrCommonConfig@16");
+        map.put("JsonSdk_GetNvrDdnsConfig", "_JsonSdk_GetNvrDdnsConfig@16");
+        map.put("JsonSdk_GetNvrDefenceParam", "_JsonSdk_GetNvrDefenceParam@12");
+        map.put("JsonSdk_GetNvrDisplayMode", "_JsonSdk_GetNvrDisplayMode@16");
+        map.put("JsonSdk_GetNvrEmailConfig", "_JsonSdk_GetNvrEmailConfig@16");
+        map.put("JsonSdk_GetNvrExceptionDetectConfig", "_JsonSdk_GetNvrExceptionDetectConfig@16");
+        map.put("JsonSdk_GetNvrFtpConfig", "_JsonSdk_GetNvrFtpConfig@16");
+        map.put("JsonSdk_GetNvrFuncState", "_JsonSdk_GetNvrFuncState@16");
+        map.put("JsonSdk_GetNvrGb28181Param", "_JsonSdk_GetNvrGb28181Param@16");
+        map.put("JsonSdk_GetNvrHotBackupConfig", "_JsonSdk_GetNvrHotBackupConfig@16");
+        map.put("JsonSdk_GetNvrIntCounterConfig", "_JsonSdk_GetNvrIntCounterConfig@16");
+        map.put("JsonSdk_GetNvrIntCounterValue", "_JsonSdk_GetNvrIntCounterValue@12");
+        map.put("JsonSdk_GetNvrModleInfo", "_JsonSdk_GetNvrModleInfo@12");
+        map.put("JsonSdk_GetNvrMonitorParam", "_JsonSdk_GetNvrMonitorParam@16");
+        map.put("JsonSdk_GetNvrNetDnsConfig", "_JsonSdk_GetNvrNetDnsConfig@16");
+        map.put("JsonSdk_GetNvrNetworkListConfig", "_JsonSdk_GetNvrNetworkListConfig@16");
+        map.put("JsonSdk_GetNvrNtpConfig", "_JsonSdk_GetNvrNtpConfig@16");
+        map.put("JsonSdk_GetNvrPhonescreenParam", "_JsonSdk_GetNvrPhonescreenParam@16");
+        map.put("JsonSdk_GetNvrPortConfig", "_JsonSdk_GetNvrPortConfig@16");
+        map.put("JsonSdk_GetNvrPppoeConfig", "_JsonSdk_GetNvrPppoeConfig@16");
+        map.put("JsonSdk_GetNvrPreviewParam", "_JsonSdk_GetNvrPreviewParam@16");
+        map.put("JsonSdk_GetNvrRecordStrategyConfig", "_JsonSdk_GetNvrRecordStrategyConfig@16");
+        map.put("JsonSdk_GetNvrSysConfig", "_JsonSdk_GetNvrSysConfig@12");
+        map.put("JsonSdk_GetNvrSysDebugInfo", "_JsonSdk_GetNvrSysDebugInfo@16");
+        map.put("JsonSdk_GetNvrSysMaintainParam", "_JsonSdk_GetNvrSysMaintainParam@16");
+        map.put("JsonSdk_GetNvrSysloglist", "_JsonSdk_GetNvrSysloglist@16");
+        map.put("JsonSdk_GetNvrUpnpConfig", "_JsonSdk_GetNvrUpnpConfig@16");
+        map.put("JsonSdk_GetNvrUserInfo", "_JsonSdk_GetNvrUserInfo@16");
+        map.put("JsonSdk_GetNvrUserPrivilege", "_JsonSdk_GetNvrUserPrivilege@12");
+        map.put("JsonSdk_GetNvrUsergroupInfo", "_JsonSdk_GetNvrUsergroupInfo@16");
+        map.put("JsonSdk_GetNvrVersionConfig", "_JsonSdk_GetNvrVersionConfig@12");
+        map.put("JsonSdk_GetNvrVideoBlindParam", "_JsonSdk_GetNvrVideoBlindParam@20");
+        map.put("JsonSdk_GetNvrVideoLossParam", "_JsonSdk_GetNvrVideoLossParam@20");
+        map.put("JsonSdk_GetNvrVideoScheduleConfig", "_JsonSdk_GetNvrVideoScheduleConfig@20");
+        map.put("JsonSdk_GetNvrVideodetectParam", "_JsonSdk_GetNvrVideodetectParam@20");
+        map.put("JsonSdk_GetNvrbroadCastConfig", "_JsonSdk_GetNvrbroadCastConfig@16");
+        map.put("JsonSdk_GetPreviewSplit", "_JsonSdk_GetPreviewSplit@12");
+        map.put("JsonSdk_GetRaidActivityEnabled", "_JsonSdk_GetRaidActivityEnabled@16");
+        map.put("JsonSdk_GetRaidActivityProgress", "_JsonSdk_GetRaidActivityProgress@16");
+        map.put("JsonSdk_GetRaidActivityRate", "_JsonSdk_GetRaidActivityRate@16");
+        map.put("JsonSdk_GetRaidCardList", "_JsonSdk_GetRaidCardList@12");
+        map.put("JsonSdk_GetRaidLogicalDiskInfo", "_JsonSdk_GetRaidLogicalDiskInfo@16");
+        map.put("JsonSdk_GetRaidPhysicalDiskList", "_JsonSdk_GetRaidPhysicalDiskList@16");
+        map.put("JsonSdk_GetReverseLinkProxyConfig", "_JsonSdk_GetReverseLinkProxyConfig@12");
+        map.put("JsonSdk_GetUpgradeFileInfo", "_JsonSdk_GetUpgradeFileInfo@12");
+        map.put("JsonSdk_GetUpgradeStatus", "_JsonSdk_GetUpgradeStatus@12");
+        map.put("JsonSdk_GetUploadFileStatus", "_JsonSdk_GetUploadFileStatus@12");
+        map.put("JsonSdk_GetVideoChannelDetectConfig", "_JsonSdk_GetVideoChannelDetectConfig@12");
+        map.put("JsonSdk_GetVideoChannelDetectParam", "_JsonSdk_GetVideoChannelDetectParam@24");
+        map.put("JsonSdk_GetVideoChannelParam", "_JsonSdk_GetVideoChannelParam@16");
+        map.put("JsonSdk_GetVideoEncoderChannelParam", "_JsonSdk_GetVideoEncoderChannelParam@16");
+        map.put("JsonSdk_IPCImageUpload", "_JsonSdk_IPCImageUpload@16");
+        map.put("JsonSdk_ImportAIUserInfo", "_JsonSdk_ImportAIUserInfo@8");
+        map.put("JsonSdk_InitLog", "_JsonSdk_InitLog@12");
+        map.put("JsonSdk_Initate", "_JsonSdk_Initate@0");
+        map.put("JsonSdk_ListIPC", "_JsonSdk_ListIPC@12");
+        map.put("JsonSdk_ListenStart", "_JsonSdk_ListenStart@8");
+        map.put("JsonSdk_ListenStartOneNvr", "_JsonSdk_ListenStartOneNvr@4");
+        map.put("JsonSdk_ListenStop", "_JsonSdk_ListenStop@0");
+        map.put("JsonSdk_ListenStopOneNvr", "_JsonSdk_ListenStopOneNvr@4");
+        map.put("JsonSdk_LockDisk", "_JsonSdk_LockDisk@8");
+        map.put("JsonSdk_Login", "_JsonSdk_Login@24");
+        map.put("JsonSdk_Logout", "_JsonSdk_Logout@4");
+        map.put("JsonSdk_ModifyAIUserInfo", "_JsonSdk_ModifyAIUserInfo@8");
+        map.put("JsonSdk_ModifyIPC", "_JsonSdk_ModifyIPC@8");
+        map.put("JsonSdk_ModifyListenPort", "_JsonSdk_ModifyListenPort@8");
+        map.put("JsonSdk_NewDataLink", "_JsonSdk_NewDataLink@8");
+        map.put("JsonSdk_PTZ3DRoomCtrl", "_JsonSdk_PTZ3DRoomCtrl@8");
+        map.put("JsonSdk_PTZCruiseStart", "_JsonSdk_PTZCruiseStart@12");
+        map.put("JsonSdk_PTZCruiseStop", "_JsonSdk_PTZCruiseStop@8");
+        map.put("JsonSdk_PTZCtrl", "_JsonSdk_PTZCtrl@16");
+        map.put("JsonSdk_PlayBackCtrl", "_JsonSdk_PlayBackCtrl@8");
+        map.put("JsonSdk_PlayBackGetPos", "_JsonSdk_PlayBackGetPos@4");
+        map.put("JsonSdk_PlayBackStartByFile", "_JsonSdk_PlayBackStartByFile@32");
+        map.put("JsonSdk_PlayBackStartByTime", "_JsonSdk_PlayBackStartByTime@36");
+        map.put("JsonSdk_PlayBackStop", "_JsonSdk_PlayBackStop@4");
+        map.put("JsonSdk_PtzControl", "_JsonSdk_PtzControl@8");
+        map.put("JsonSdk_QueryAlarmLog", "_JsonSdk_QueryAlarmLog@12");
+        map.put("JsonSdk_QueryAlarmLogClose", "_JsonSdk_QueryAlarmLogClose@4");
+        map.put("JsonSdk_QueryFileCount", "_JsonSdk_QueryFileCount@12");
+        map.put("JsonSdk_QueryLogClose", "_JsonSdk_QueryLogClose@4");
+        map.put("JsonSdk_QueryNVRLog", "_JsonSdk_QueryNVRLog@12");
+        map.put("JsonSdk_QueryNextAlarmLog", "_JsonSdk_QueryNextAlarmLog@12");
+        map.put("JsonSdk_QueryNextLog", "_JsonSdk_QueryNextLog@12");
+        map.put("JsonSdk_RaidLocateDisk", "_JsonSdk_RaidLocateDisk@8");
+        map.put("JsonSdk_Reboot", "_JsonSdk_Reboot@4");
+        map.put("JsonSdk_RecordStart", "_JsonSdk_RecordStart@12");
+        map.put("JsonSdk_RecordStop", "_JsonSdk_RecordStop@8");
+        map.put("JsonSdk_RecoverNvrBackup", "_JsonSdk_RecoverNvrBackup@8");
+        map.put("JsonSdk_RemoveIPC", "_JsonSdk_RemoveIPC@8");
+        map.put("JsonSdk_ReqModifyUserGroupInfo", "_JsonSdk_ReqModifyUserGroupInfo@8");
+        map.put("JsonSdk_ReqModifyUserInfo", "_JsonSdk_ReqModifyUserInfo@8");
+        map.put("JsonSdk_RestoreAlarmInDetectParam", "_JsonSdk_RestoreAlarmInDetectParam@4");
+        map.put("JsonSdk_RestoreAllConfig", "_JsonSdk_RestoreAllConfig@4");
+        map.put("JsonSdk_RestoreDefalutAllNetworkInfo", "_JsonSdk_RestoreDefalutAllNetworkInfo@4");
+        map.put("JsonSdk_RestoreDefaultUserInfo", "_JsonSdk_RestoreDefaultUserInfo@4");
+        map.put("JsonSdk_RestoreDiskGroupParam", "_JsonSdk_RestoreDiskGroupParam@4");
+        map.put("JsonSdk_RestoreExceptionDetectParam", "_JsonSdk_RestoreExceptionDetectParam@4");
+        map.put("JsonSdk_RestoreNvrCommonConfig", "_JsonSdk_RestoreNvrCommonConfig@4");
+        map.put("JsonSdk_RestoreNvrMonitorParam", "_JsonSdk_RestoreNvrMonitorParam@4");
+        map.put("JsonSdk_RestoreNvrPreviewParam", "_JsonSdk_RestoreNvrPreviewParam@4");
+        map.put("JsonSdk_RestoreNvrSysMaintainParam", "_JsonSdk_RestoreNvrSysMaintainParam@4");
+        map.put("JsonSdk_RestorePreviewSplit", "_JsonSdk_RestorePreviewSplit@4");
+        map.put("JsonSdk_RestoreVideoChannelDetectParam", "_JsonSdk_RestoreVideoChannelDetectParam@4");
+        map.put("JsonSdk_RestoreVideoScheduleConfig", "_JsonSdk_RestoreVideoScheduleConfig@4");
+        map.put("JsonSdk_SearchFile", "_JsonSdk_SearchFile@12");
+        map.put("JsonSdk_SearchFileClose", "_JsonSdk_SearchFileClose@4");
+        map.put("JsonSdk_SearchFileExisted", "_JsonSdk_SearchFileExisted@12");
+        map.put("JsonSdk_SearchIPC", "_JsonSdk_SearchIPC@12");
+        map.put("JsonSdk_SearchNextFile", "_JsonSdk_SearchNextFile@12");
+        map.put("JsonSdk_SearchOnlineUser", "_JsonSdk_SearchOnlineUser@12");
+        map.put("JsonSdk_SetAlarmInDetectParam", "_JsonSdk_SetAlarmInDetectParam@8");
+        map.put("JsonSdk_SetCameraAlarmDetectParam", "_JsonSdk_SetCameraAlarmDetectParam@8");
+        map.put("JsonSdk_SetCruiseParam", "_JsonSdk_SetCruiseParam@8");
+        map.put("JsonSdk_SetDecIPC", "_JsonSdk_SetDecIPC@12");
+        map.put("JsonSdk_SetDiskGroupChannelParam", "_JsonSdk_SetDiskGroupChannelParam@8");
+        map.put("JsonSdk_SetDiskGroupDiskParam", "_JsonSdk_SetDiskGroupDiskParam@8");
+        map.put("JsonSdk_SetExceptionDetectParam", "_JsonSdk_SetExceptionDetectParam@8");
+        map.put("JsonSdk_SetFacePictureAlarmInfo", "_JsonSdk_SetFacePictureAlarmInfo@8");
+        map.put("JsonSdk_SetFacePictureBaseConfig", "_JsonSdk_SetFacePictureBaseConfig@8");
+        map.put("JsonSdk_SetFilePlayBackPos", "_JsonSdk_SetFilePlayBackPos@12");
+        map.put("JsonSdk_SetIpcStreamTransPort", "_JsonSdk_SetIpcStreamTransPort@8");
+        map.put("JsonSdk_SetMonitorChecker", "_JsonSdk_SetMonitorChecker@8");
+        map.put("JsonSdk_SetMonitorMaintain", "_JsonSdk_SetMonitorMaintain@8");
+        map.put("JsonSdk_SetMonitorRepair", "_JsonSdk_SetMonitorRepair@8");
+        map.put("JsonSdk_SetNVRConfig", "_JsonSdk_SetNVRConfig@20");
+        map.put("JsonSdk_SetNVRTime", "_JsonSdk_SetNVRTime@8");
+        map.put("JsonSdk_SetNvrAlarmCenterParam", "_JsonSdk_SetNvrAlarmCenterParam@8");
+        map.put("JsonSdk_SetNvrAlarmOutDetectConfig", "_JsonSdk_SetNvrAlarmOutDetectConfig@8");
+        map.put("JsonSdk_SetNvrAlarmOutStrategy", "_JsonSdk_SetNvrAlarmOutStrategy@8");
+        map.put("JsonSdk_SetNvrBroadCastConfig", "_JsonSdk_SetNvrBroadCastConfig@8");
+        map.put("JsonSdk_SetNvrCommonConfig", "_JsonSdk_SetNvrCommonConfig@8");
+        map.put("JsonSdk_SetNvrDdnsConfig", "_JsonSdk_SetNvrDdnsConfig@8");
+        map.put("JsonSdk_SetNvrDefenceParam", "_JsonSdk_SetNvrDefenceParam@8");
+        map.put("JsonSdk_SetNvrDisplayMode", "_JsonSdk_SetNvrDisplayMode@8");
+        map.put("JsonSdk_SetNvrEmailConfig", "_JsonSdk_SetNvrEmailConfig@8");
+        map.put("JsonSdk_SetNvrExceptionDetectConfig", "_JsonSdk_SetNvrExceptionDetectConfig@8");
+        map.put("JsonSdk_SetNvrFtpConfig", "_JsonSdk_SetNvrFtpConfig@8");
+        map.put("JsonSdk_SetNvrFuncState", "_JsonSdk_SetNvrFuncState@8");
+        map.put("JsonSdk_SetNvrGb28181Param", "_JsonSdk_SetNvrGb28181Param@8");
+        map.put("JsonSdk_SetNvrHotBackupConfig", "_JsonSdk_SetNvrHotBackupConfig@8");
+        map.put("JsonSdk_SetNvrIntCounterConfig", "_JsonSdk_SetNvrIntCounterConfig@12");
+        map.put("JsonSdk_SetNvrModleInfo", "_JsonSdk_SetNvrModleInfo@8");
+        map.put("JsonSdk_SetNvrMonitorParam", "_JsonSdk_SetNvrMonitorParam@8");
+        map.put("JsonSdk_SetNvrNetDnsConfig", "_JsonSdk_SetNvrNetDnsConfig@8");
+        map.put("JsonSdk_SetNvrNetworkListConfig", "_JsonSdk_SetNvrNetworkListConfig@8");
+        map.put("JsonSdk_SetNvrNtpConfig", "_JsonSdk_SetNvrNtpConfig@8");
+        map.put("JsonSdk_SetNvrPhonescreenParam", "_JsonSdk_SetNvrPhonescreenParam@8");
+        map.put("JsonSdk_SetNvrPortConfig", "_JsonSdk_SetNvrPortConfig@8");
+        map.put("JsonSdk_SetNvrPppoeConfig", "_JsonSdk_SetNvrPppoeConfig@8");
+        map.put("JsonSdk_SetNvrPreviewParam", "_JsonSdk_SetNvrPreviewParam@8");
+        map.put("JsonSdk_SetNvrRecordStrategyConfig", "_JsonSdk_SetNvrRecordStrategyConfig@8");
+        map.put("JsonSdk_SetNvrSysDebugInfo", "_JsonSdk_SetNvrSysDebugInfo@8");
+        map.put("JsonSdk_SetNvrSysMaintainParam", "_JsonSdk_SetNvrSysMaintainParam@8");
+        map.put("JsonSdk_SetNvrSyslogInfo", "_JsonSdk_SetNvrSyslogInfo@8");
+        map.put("JsonSdk_SetNvrUpnpConfig", "_JsonSdk_SetNvrUpnpConfig@8");
+        map.put("JsonSdk_SetNvrVideoBlindParam", "_JsonSdk_SetNvrVideoBlindParam@8");
+        map.put("JsonSdk_SetNvrVideoLossParam", "_JsonSdk_SetNvrVideoLossParam@8");
+        map.put("JsonSdk_SetNvrVideoScheduleConfig", "_JsonSdk_SetNvrVideoScheduleConfig@8");
+        map.put("JsonSdk_SetNvrVideodetectParam", "_JsonSdk_SetNvrVideodetectParam@8");
+        map.put("JsonSdk_SetPreviewSplit", "_JsonSdk_SetPreviewSplit@8");
+        map.put("JsonSdk_SetRaidActivityEnabled", "_JsonSdk_SetRaidActivityEnabled@8");
+        map.put("JsonSdk_SetRaidActivityRate", "_JsonSdk_SetRaidActivityRate@8");
+        map.put("JsonSdk_SetRaidCardCache", "_JsonSdk_SetRaidCardCache@8");
+        map.put("JsonSdk_SetReqTimeOut", "_JsonSdk_SetReqTimeOut@4");
+        map.put("JsonSdk_SetReverseLinkProxedInfo", "_JsonSdk_SetReverseLinkProxedInfo@8");
+        map.put("JsonSdk_SetReverseLinkProxyProtocol", "_JsonSdk_SetReverseLinkProxyProtocol@8");
+        map.put("JsonSdk_SetTimePlayBackPos", "_JsonSdk_SetTimePlayBackPos@12");
+        map.put("JsonSdk_SetVideoChannelDetectParam", "_JsonSdk_SetVideoChannelDetectParam@12");
+        map.put("JsonSdk_SetVideoChannelParam", "_JsonSdk_SetVideoChannelParam@8");
+        map.put("JsonSdk_SetVideoEncoderChannelParam", "_JsonSdk_SetVideoEncoderChannelParam@8");
+        map.put("JsonSdk_SetVolume", "_JsonSdk_SetVolume@8");
+        map.put("JsonSdk_ShutDown", "_JsonSdk_ShutDown@4");
+        map.put("JsonSdk_SilenceRaidAlarm", "_JsonSdk_SilenceRaidAlarm@8");
+        map.put("JsonSdk_StartRaidActivity", "_JsonSdk_StartRaidActivity@8");
+        map.put("JsonSdk_StartSearchNvr", "_JsonSdk_StartSearchNvr@8");
+        map.put("JsonSdk_StartSendDebugLog", "_JsonSdk_StartSendDebugLog@12");
+        map.put("JsonSdk_StopSearchNvr", "_JsonSdk_StopSearchNvr@0");
+        map.put("JsonSdk_StopSendDebugLog", "_JsonSdk_StopSendDebugLog@4");
+        map.put("JsonSdk_StopUploadFile", "_JsonSdk_StopUploadFile@4");
+        map.put("JsonSdk_TalkStart", "_JsonSdk_TalkStart@24");
+        map.put("JsonSdk_TalkStop", "_JsonSdk_TalkStop@4");
+        map.put("JsonSdk_TestExitNvrapp", "_JsonSdk_TestExitNvrapp@4");
+        map.put("JsonSdk_UnlockDisk", "_JsonSdk_UnlockDisk@8");
+        map.put("JsonSdk_UpgradeStart", "_JsonSdk_UpgradeStart@8");
+        map.put("JsonSdk_UpgradeStop", "_JsonSdk_UpgradeStop@4");
+        map.put("JsonSdk_UploadUpgradeFile", "_JsonSdk_UploadUpgradeFile@12");
+        map.put("JsonSdk_VideoTranspondStart", "_JsonSdk_VideoTranspondStart@28");
+        map.put("JsonSdk_VideoTranspondStartWithoutViskhead", "_JsonSdk_VideoTranspondStartWithoutViskhead@28");
+        map.put("JsonSdk_VideoTranspondStop", "_JsonSdk_VideoTranspondStop@4");
+        map.put("JsonSdk_SetVideoNoVskHeadFrameCallBack", "_JsonSdk_SetVideoNoVskHeadFrameCallBack@4");
+    }
+
+    /**
+     * 根据函数名取其在dll中的名称
+     *
+     * @param   library         库
+     * @param   method          该当
+     * @return  返回在动态库中的名称
+     */
+    @Override
+    public String getFunctionName(NativeLibrary library, Method method) {
+        String name = map.get(method.getName());
+        return name == null ? method.getName() : name;
+    }
+}

+ 9 - 0
src/main/java/com/persagy/nvr/VIDEO_DETECT_TYPE.java

@@ -0,0 +1,9 @@
+package com.persagy.nvr;
+
+public enum VIDEO_DETECT_TYPE {
+	
+    VIDEO_DETECT_TYPE_MOTION,	// Motion detecting
+    VIDEO_DETECT_TYPE_LOSS,		// Video loss
+    VIDEO_DETECT_TYPE_BLIND	    // Video shade
+    
+}

+ 62 - 0
src/main/java/com/persagy/nvr/VideoNoViskHeadFrameCallBackClass.java

@@ -0,0 +1,62 @@
+package com.persagy.nvr;
+
+import com.persagy.cameractl.conf.AllStaticConfig;
+import com.persagy.nvr.VskClient.VideoNoViskHeadFrameInfo;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class VideoNoViskHeadFrameCallBackClass implements VskClient.VideoNoViskHeadFrameCallBack {
+
+	@Override
+	public void Callback(Pointer pFrameBuf, int nFrameLen, Pointer pStream, Pointer pUser) {
+		try {
+			if (pFrameBuf == null || pStream == null) {
+				log.info("自定义回调没数据");
+				return;
+			}
+
+			VideoNoViskHeadFrameInfo videoNoViskHeadFrameInfo = Structure.newInstance(VideoNoViskHeadFrameInfo.class,
+					pStream);
+			videoNoViskHeadFrameInfo.read();
+
+			int encodeType = videoNoViskHeadFrameInfo.nEncodeType.intValue();
+			if (encodeType != 26) {
+				log.warn("非h264编码,当前编码类型枚举值为:" + encodeType);
+			}
+
+			byte[] byteArr = pFrameBuf.getByteArray(0, nFrameLen);
+			AllStaticConfig.backByteBufferList.add(byteArr);
+		} catch (Exception e) {
+			log.error("自定义回调执行异常", e);
+		}
+	}
+}
+
+// 编码类型
+// E_PT_MPEG2TS = 1, // MPEG-2 Transport Stream
+// E_PT_QCELP = 2,// QCELP audio
+// E_PT_AMR = 3,// AMR audio (narrowband)
+// E_PT_AMR_WB = 4,// AMR audio (wideband)
+// E_PT_MPEGAUDIO = 5,// MPEG-1 or 2 audio
+// E_PT_MP4AUDIO = 6,// MPEG-4 LATM audio
+// E_PT_PCM8 = 7,// PCM u-law audio
+// E_PT_AC3 = 8,// AC3 audio
+// E_PT_MPEG4V_ES = 9,// MPEG-4 ES
+// E_PT_MPVIDEO = 10,// MPEG-1 or 2 video
+//
+// E_PT_PCMA = 14, // VSK_G711A
+// E_PT_PCMU = 22, // VSK_G711U
+//
+// E_PT_H261 = 24,// H.261
+// E_PT_H263 = 25,// H.263
+// E_PT_H264 = 26,// H.264 视频帧类型
+// E_PT_MJPEG = 27,// motion JPEG
+//
+// E_PT_G726_16 = 28,// G.726, 16 kbps
+// E_PT_G726_24 = 29,// G.726, 24 kbps
+// E_PT_G726_32 = 30,// G.726, 32 kbps
+// E_PT_G726_40 = 31,// G.726, 40 kbps
+// E_PT_H265 = 35,// H.265 视频帧类型

Datei-Diff unterdrückt, da er zu groß ist
+ 3379 - 0
src/main/java/com/persagy/nvr/VskClient.java


+ 280 - 0
src/main/java/com/persagy/vsknet/SdkMapper.java

@@ -0,0 +1,280 @@
+package com.persagy.vsknet;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+
+import com.sun.jna.FunctionMapper;
+import com.sun.jna.NativeLibrary;
+
+/**
+ * 函数名称映射类
+ *
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class SdkMapper implements FunctionMapper {
+	
+    /** 保存函数名映射关系 */
+    private HashMap<String, String> map = new HashMap<String, String>();
+
+    /**
+     * 构造函数
+     */
+    public SdkMapper() {
+        /** 在此填写函数名映射关系 */
+        map.put("NS_NET_59aUpgradeStart", "_NS_NET_59aUpgradeStart@16");
+        map.put("NS_NET_59aUpgradeStartEx", "_NS_NET_59aUpgradeStartEx@12");
+        map.put("NS_NET_59aUpgradeStop", "_NS_NET_59aUpgradeStop@4");
+        map.put("NS_NET_59aUpgradeStopEx", "_NS_NET_59aUpgradeStopEx@4");
+        map.put("NS_NET_AddChannel", "_NS_NET_AddChannel@532");
+        map.put("NS_NET_AddFaceDataBase", "_NS_NET_AddFaceDataBase@12");
+        map.put("NS_NET_AddIPC", "_NS_NET_AddIPC@384");
+        map.put("NS_NET_AddIVSUserInfo", "_NS_NET_AddIVSUserInfo@12");
+        map.put("NS_NET_AddNvrRouteInfo", "_NS_NET_AddNvrRouteInfo@8");
+        map.put("NS_NET_AdjustTime", "_NS_NET_AdjustTime@36");
+        map.put("NS_NET_ChannelConfigExport", "_NS_NET_ChannelConfigExport@16");
+        map.put("NS_NET_ChannelConfigImport", "_NS_NET_ChannelConfigImport@12");
+        map.put("NS_NET_Clear", "_NS_NET_Clear@0");
+        map.put("NS_NET_ClearOnlineUser", "_NS_NET_ClearOnlineUser@8");
+        map.put("NS_NET_CommonDownloadPictureFile", "_NS_NET_CommonDownloadPictureFile@16");
+        map.put("NS_NET_CommonPictureFileDownload", "_NS_NET_CommonPictureFileDownload@16");
+        map.put("NS_NET_ConfigExport", "_NS_NET_ConfigExport@16");
+        map.put("NS_NET_ConfigImport", "_NS_NET_ConfigImport@12");
+        map.put("NS_NET_CtrlPlayBack_Proxy", "_NS_NET_CtrlPlayBack_Proxy@16");
+        map.put("NS_NET_CtrlPlayBack_Trans", "_NS_NET_CtrlPlayBack_Trans@16");
+        map.put("NS_NET_DataBaseAddCarInfo", "_NS_NET_DataBaseAddCarInfo@12");
+        map.put("NS_NET_DataBaseDelCarInfo", "_NS_NET_DataBaseDelCarInfo@8");
+        map.put("NS_NET_DataBaseImport", "_NS_NET_DataBaseImport@12");
+        map.put("NS_NET_DataBaseModCarInfo", "_NS_NET_DataBaseModCarInfo@12");
+        map.put("NS_NET_DelFaceDataBase", "_NS_NET_DelFaceDataBase@8");
+        map.put("NS_NET_DelIVSUserInfo", "_NS_NET_DelIVSUserInfo@8");
+        map.put("NS_NET_DelNvrRouteInfo", "_NS_NET_DelNvrRouteInfo@8");
+        map.put("NS_NET_DownloadCarPictureFile", "_NS_NET_DownloadCarPictureFile@12");
+        map.put("NS_NET_DownloadGetPos", "_NS_NET_DownloadGetPos@4");
+        map.put("NS_NET_DownloadIVSPicture", "_NS_NET_DownloadIVSPicture@16");
+        map.put("NS_NET_DownloadPictureFile", "_NS_NET_DownloadPictureFile@12");
+        map.put("NS_NET_DownloadStart", "_NS_NET_DownloadStart@24");
+        map.put("NS_NET_DownloadStop", "_NS_NET_DownloadStop@4");
+        map.put("NS_NET_ExceptionCallBack", "_NS_NET_ExceptionCallBack@16");
+        map.put("NS_NET_FileLock", "_NS_NET_FileLock@8");
+        map.put("NS_NET_FileUnlock", "_NS_NET_FileUnlock@8");
+        map.put("NS_NET_FreeBuffer", "_NS_NET_FreeBuffer@4");
+        map.put("NS_NET_Get59aUpgradePos", "_NS_NET_Get59aUpgradePos@4");
+        map.put("NS_NET_Get59aUpgradePosEx", "_NS_NET_Get59aUpgradePosEx@4");
+        map.put("NS_NET_Get59aUpgradeState", "_NS_NET_Get59aUpgradeState@4");
+        map.put("NS_NET_Get59aUpgradeStateEx", "_NS_NET_Get59aUpgradeStateEx@4");
+        map.put("NS_NET_GetAgboxConfigInfo", "_NS_NET_GetAgboxConfigInfo@12");
+        map.put("NS_NET_GetAlarmToneConfigInfo", "_NS_NET_GetAlarmToneConfigInfo@16");
+        map.put("NS_NET_GetCMSChlInfo", "_NS_NET_GetCMSChlInfo@12");
+        map.put("NS_NET_GetCruisePara", "_NS_NET_GetCruisePara@12");
+        map.put("NS_NET_GetDecAlarmStrategy", "_NS_NET_GetDecAlarmStrategy@8");
+        map.put("NS_NET_GetDecCirculatePlayStrategy", "_NS_NET_GetDecCirculatePlayStrategy@8");
+        map.put("NS_NET_GetDecPreviewParam", "_NS_NET_GetDecPreviewParam@8");
+        map.put("NS_NET_GetDiskInfo", "_NS_NET_GetDiskInfo@8");
+        map.put("NS_NET_GetErrMsg", "_NS_NET_GetErrMsg@12");
+        map.put("NS_NET_GetLastErr", "_NS_NET_GetLastErr@0");
+        map.put("NS_NET_GetNVRConfig", "_NS_NET_GetNVRConfig@24");
+        map.put("NS_NET_GetNVRConfigEx", "_NS_NET_GetNVRConfigEx@32");
+        map.put("NS_NET_GetNVRFaceAlarmConfig", "_NS_NET_GetNVRFaceAlarmConfig@8");
+        map.put("NS_NET_GetNVRTime", "_NS_NET_GetNVRTime@8");
+        map.put("NS_NET_GetNvrAutoRecScheParam", "_NS_NET_GetNvrAutoRecScheParam@12");
+        map.put("NS_NET_GetNvrChannelListInfo", "_NS_NET_GetNvrChannelListInfo@20");
+        map.put("NS_NET_GetNvrChlGbIDInfo", "_NS_NET_GetNvrChlGbIDInfo@16");
+        map.put("NS_NET_GetNvrChlNameInfo", "_NS_NET_GetNvrChlNameInfo@16");
+        map.put("NS_NET_GetNvrDiskAutoSleepState", "_NS_NET_GetNvrDiskAutoSleepState@8");
+        map.put("NS_NET_GetNvrExceptionInfo", "_NS_NET_GetNvrExceptionInfo@16");
+        map.put("NS_NET_GetNvrFaceAlarmPersonInfo", "_NS_NET_GetNvrFaceAlarmPersonInfo@12");
+        map.put("NS_NET_GetNvrHighTemperAlarmThreshold", "_NS_NET_GetNvrHighTemperAlarmThreshold@8");
+        map.put("NS_NET_GetNvrMixAI59aConfigInfo", "_NS_NET_GetNvrMixAI59aConfigInfo@8");
+        map.put("NS_NET_GetNvrModleInfo", "_NS_NET_GetNvrModleInfo@8");
+        map.put("NS_NET_GetNvrRecStraParam", "_NS_NET_GetNvrRecStraParam@12");
+        map.put("NS_NET_GetNvrRouteTableInfo", "_NS_NET_GetNvrRouteTableInfo@16");
+        map.put("NS_NET_GetNvrServerUrlLIstInfo", "_NS_NET_GetNvrServerUrlLIstInfo@16");
+        map.put("NS_NET_GetNvrVersionInfo", "_NS_NET_GetNvrVersionInfo@8");
+        map.put("NS_NET_GetOldPeopleStatuInfo", "_NS_NET_GetOldPeopleStatuInfo@8");
+        map.put("NS_NET_GetSmartBoxConfig", "_NS_NET_GetSmartBoxConfig@8");
+        map.put("NS_NET_GetSmartBoxState", "_NS_NET_GetSmartBoxState@16");
+        map.put("NS_NET_GetUpgradePos", "_NS_NET_GetUpgradePos@4");
+        map.put("NS_NET_GetUpgradeState", "_NS_NET_GetUpgradeState@4");
+        map.put("NS_NET_GetVideoTranspondID", "_NS_NET_GetVideoTranspondID@12");
+        map.put("NS_NET_Initate", "_NS_NET_Initate@0");
+        map.put("NS_NET_ListenStart", "_NS_NET_ListenStart@12");
+        map.put("NS_NET_ListenStartOneNvr", "_NS_NET_ListenStartOneNvr@4");
+        map.put("NS_NET_ListenStop", "_NS_NET_ListenStop@0");
+        map.put("NS_NET_LockDisk", "_NS_NET_LockDisk@8");
+        map.put("NS_NET_Login", "_NS_NET_Login@24");
+        map.put("NS_NET_Logout", "_NS_NET_Logout@4");
+        map.put("NS_NET_ModFaceDataBase", "_NS_NET_ModFaceDataBase@12");
+        map.put("NS_NET_ModIVSUserInfo", "_NS_NET_ModIVSUserInfo@12");
+        map.put("NS_NET_ModifyIPC", "_NS_NET_ModifyIPC@384");
+        map.put("NS_NET_ModifyListenPort", "_NS_NET_ModifyListenPort@8");
+        map.put("NS_NET_OldPeopleStatuInfoCloseQuery", "_NS_NET_OldPeopleStatuInfoCloseQuery@4");
+        map.put("NS_NET_OpenMixAISubscriptionRequest", "_NS_NET_OpenMixAISubscriptionRequest@16");
+        map.put("NS_NET_PTZCruiseStart", "_NS_NET_PTZCruiseStart@12");
+        map.put("NS_NET_PTZCruiseStop", "_NS_NET_PTZCruiseStop@8");
+        map.put("NS_NET_PTZCtrl", "_NS_NET_PTZCtrl@16");
+        map.put("NS_NET_PictureStorageGetDiskConfig", "_NS_NET_PictureStorageGetDiskConfig@12");
+        map.put("NS_NET_PictureStorageGetNetConfig", "_NS_NET_PictureStorageGetNetConfig@12");
+        map.put("NS_NET_PictureStorageGetUploadUrl", "_NS_NET_PictureStorageGetUploadUrl@12");
+        map.put("NS_NET_PictureStorageSetDiskConfig", "_NS_NET_PictureStorageSetDiskConfig@12");
+        map.put("NS_NET_PictureStorageSetNetConfig", "_NS_NET_PictureStorageSetNetConfig@8");
+        map.put("NS_NET_PictureStorageSetUploadUrl", "_NS_NET_PictureStorageSetUploadUrl@8");
+        map.put("NS_NET_PlayBackCtrl", "_NS_NET_PlayBackCtrl@24");
+        map.put("NS_NET_PlayBackGetPos", "_NS_NET_PlayBackGetPos@4");
+        map.put("NS_NET_PlayBackStartByName", "_NS_NET_PlayBackStartByName@24");
+        map.put("NS_NET_PlayBackStartByNameEx", "_NS_NET_PlayBackStartByNameEx@24");
+        map.put("NS_NET_PlayBackStartByNameExNew", "_NS_NET_PlayBackStartByNameExNew@28");
+        map.put("NS_NET_PlayBackStartByNameNew", "_NS_NET_PlayBackStartByNameNew@28");
+        map.put("NS_NET_PlayBackStartByTime", "_NS_NET_PlayBackStartByTime@28");
+        map.put("NS_NET_PlayBackStartByTimeEx", "_NS_NET_PlayBackStartByTimeEx@28");
+        map.put("NS_NET_PlayBackStartByTimeExNew", "_NS_NET_PlayBackStartByTimeExNew@32");
+        map.put("NS_NET_PlayBackStartByTimeNew", "_NS_NET_PlayBackStartByTimeNew@32");
+        map.put("NS_NET_PlayBackStop", "_NS_NET_PlayBackStop@4");
+        map.put("NS_NET_PreviewSplit", "_NS_NET_PreviewSplit@12");
+        map.put("NS_NET_QueryCarPictureFileCount", "_NS_NET_QueryCarPictureFileCount@12");
+        map.put("NS_NET_QueryFaceAlarmCount", "_NS_NET_QueryFaceAlarmCount@8");
+        map.put("NS_NET_QueryFaceAlarmInfo", "_NS_NET_QueryFaceAlarmInfo@16");
+        map.put("NS_NET_QueryFacePictureFileCount", "_NS_NET_QueryFacePictureFileCount@8");
+        map.put("NS_NET_QueryLogClose", "_NS_NET_QueryLogClose@4");
+        map.put("NS_NET_QueryMotorPicCount", "_NS_NET_QueryMotorPicCount@12");
+        map.put("NS_NET_QueryMotorPicInfo", "_NS_NET_QueryMotorPicInfo@8");
+        map.put("NS_NET_QueryMotorPictureClose", "_NS_NET_QueryMotorPictureClose@4");
+        map.put("NS_NET_QueryNVRLog", "_NS_NET_QueryNVRLog@16");
+        map.put("NS_NET_QueryNetWorkAlarmConfigInfo", "_NS_NET_QueryNetWorkAlarmConfigInfo@12");
+        map.put("NS_NET_QueryNextLog", "_NS_NET_QueryNextLog@8");
+        map.put("NS_NET_QueryNextMotorPicInfo", "_NS_NET_QueryNextMotorPicInfo@8");
+        map.put("NS_NET_QueryNextNonMotorPicInfo", "_NS_NET_QueryNextNonMotorPicInfo@8");
+        map.put("NS_NET_QueryNextPeoplePicInfo", "_NS_NET_QueryNextPeoplePicInfo@8");
+        map.put("NS_NET_QueryNextThermometryPictureInfo", "_NS_NET_QueryNextThermometryPictureInfo@8");
+        map.put("NS_NET_QueryNonMotorPicCount", "_NS_NET_QueryNonMotorPicCount@12");
+        map.put("NS_NET_QueryNonMotorPicInfo", "_NS_NET_QueryNonMotorPicInfo@8");
+        map.put("NS_NET_QueryNonMotorPictureClose", "_NS_NET_QueryNonMotorPictureClose@4");
+        map.put("NS_NET_QueryOldPeopleStatuCount", "_NS_NET_QueryOldPeopleStatuCount@8");
+        map.put("NS_NET_QueryPeoplePicCount", "_NS_NET_QueryPeoplePicCount@12");
+        map.put("NS_NET_QueryPeoplePicInfo", "_NS_NET_QueryPeoplePicInfo@8");
+        map.put("NS_NET_QueryPeoplePictureClose", "_NS_NET_QueryPeoplePictureClose@4");
+        map.put("NS_NET_QueryPictureFileCount", "_NS_NET_QueryPictureFileCount@8");
+        map.put("NS_NET_QueryTargetLibraryManagementInfo", "_NS_NET_QueryTargetLibraryManagementInfo@12");
+        map.put("NS_NET_QueryThermometryPictureClose", "_NS_NET_QueryThermometryPictureClose@4");
+        map.put("NS_NET_QueryThermometryPictureCount", "_NS_NET_QueryThermometryPictureCount@12");
+        map.put("NS_NET_QueryThermometryPictureInfo", "_NS_NET_QueryThermometryPictureInfo@8");
+        map.put("NS_NET_QueryWisdomPlatConfigInfo", "_NS_NET_QueryWisdomPlatConfigInfo@12");
+        map.put("NS_NET_Reboot", "_NS_NET_Reboot@4");
+        map.put("NS_NET_RemoveIPC", "_NS_NET_RemoveIPC@8");
+        map.put("NS_NET_RestorePreviewSplit", "_NS_NET_RestorePreviewSplit@4");
+        map.put("NS_NET_SearchByImage", "_NS_NET_SearchByImage@16");
+        map.put("NS_NET_SearchByPictureFileClose", "_NS_NET_SearchByPictureFileClose@4");
+        map.put("NS_NET_SearchByPictureNextFile", "_NS_NET_SearchByPictureNextFile@8");
+        map.put("NS_NET_SearchCarInfo", "_NS_NET_SearchCarInfo@8");
+        map.put("NS_NET_SearchCarInfoClose", "_NS_NET_SearchCarInfoClose@4");
+        map.put("NS_NET_SearchCarPlateFile", "_NS_NET_SearchCarPlateFile@8");
+        map.put("NS_NET_SearchCarPlateFileClose", "_NS_NET_SearchCarPlateFileClose@4");
+        map.put("NS_NET_SearchFacePictureFile", "_NS_NET_SearchFacePictureFile@8");
+        map.put("NS_NET_SearchFacePictureFileClose", "_NS_NET_SearchFacePictureFileClose@4");
+        map.put("NS_NET_SearchFile", "_NS_NET_SearchFile@8");
+        map.put("NS_NET_SearchFileClose", "_NS_NET_SearchFileClose@4");
+        map.put("NS_NET_SearchFileExisted", "_NS_NET_SearchFileExisted@12");
+        map.put("NS_NET_SearchIPC", "_NS_NET_SearchIPC@12");
+        map.put("NS_NET_SearchIVSPictureFile", "_NS_NET_SearchIVSPictureFile@8");
+        map.put("NS_NET_SearchIVSPictureFileClose", "_NS_NET_SearchIVSPictureFileClose@4");
+        map.put("NS_NET_SearchNextCarInfo", "_NS_NET_SearchNextCarInfo@8");
+        map.put("NS_NET_SearchNextCarPlateFile", "_NS_NET_SearchNextCarPlateFile@8");
+        map.put("NS_NET_SearchNextFacePictureFile", "_NS_NET_SearchNextFacePictureFile@8");
+        map.put("NS_NET_SearchNextFile", "_NS_NET_SearchNextFile@8");
+        map.put("NS_NET_SearchNextIVSPictureFile", "_NS_NET_SearchNextIVSPictureFile@8");
+        map.put("NS_NET_SearchNextPictureFile", "_NS_NET_SearchNextPictureFile@8");
+        map.put("NS_NET_SearchOnlineUser", "_NS_NET_SearchOnlineUser@12");
+        map.put("NS_NET_SearchPictureFile", "_NS_NET_SearchPictureFile@8");
+        map.put("NS_NET_SearchPictureFileClose", "_NS_NET_SearchFacePictureFileClose@4");
+        map.put("NS_NET_SendJsonMsgToNvr", "_NS_NET_SendJsonMsgToNvr@20");
+        map.put("NS_NET_SendTalkDataProxy", "_NS_NET_SendTalkDataProxy@16");
+        map.put("NS_NET_SetAgboxConfigInfo", "_NS_NET_SetAgboxConfigInfo@12");
+        map.put("NS_NET_SetAlarmToneConfigInfo", "_NS_NET_SetAlarmToneConfigInfo@16");
+        map.put("NS_NET_SetCMSChlInfo", "_NS_NET_SetCMSChlInfo@12");
+        map.put("NS_NET_SetCMSInfo", "_NS_NET_SetCMSInfo@8");
+        map.put("NS_NET_SetCruisePara", "_NS_NET_SetCruisePara@12");
+        map.put("NS_NET_SetDecAlarmStrategy", "_NS_NET_SetDecAlarmStrategy@8");
+        map.put("NS_NET_SetDecCirculatePlayStrategy", "_NS_NET_SetDecCirculatePlayStrategy@8");
+        map.put("NS_NET_SetDecIPC", "_NS_NET_SetDecIPC@12");
+        map.put("NS_NET_SetDecPreviewParam", "_NS_NET_SetDecPreviewParam@8");
+        map.put("NS_NET_SetNVRConfig", "_NS_NET_SetNVRConfig@20");
+        map.put("NS_NET_SetNVRFaceAlarmConfig", "_NS_NET_SetNVRFaceAlarmConfig@8");
+        map.put("NS_NET_SetNVRTelnetPaswd", "_NS_NET_SetNVRTelnetPaswd@8");
+        map.put("NS_NET_SetNetWorkAlarmConfigInfo", "_NS_NET_SetNetWorkAlarmConfigInfo@8");
+        map.put("NS_NET_SetNvrAutoRecScheParam", "_NS_NET_SetNvrAutoRecScheParam@8");
+        map.put("NS_NET_SetNvrChlGbIDInfo", "_NS_NET_SetNvrChlGbIDInfo@8");
+        map.put("NS_NET_SetNvrChlNameInfo", "_NS_NET_SetNvrChlNameInfo@8");
+        map.put("NS_NET_SetNvrDiskAutoSleepState", "_NS_NET_SetNvrDiskAutoSleepState@8");
+        map.put("NS_NET_SetNvrHighTemperAlarmThreshold", "_NS_NET_SetNvrHighTemperAlarmThreshold@8");
+        map.put("NS_NET_SetNvrMixAI59aConfigInfo", "_NS_NET_SetNvrMixAI59aConfigInfo@8");
+        map.put("NS_NET_SetNvrRecStraParam", "_NS_NET_SetNvrRecStraParam@8");
+        map.put("NS_NET_SetPlayBackEndCallBack", "_NS_NET_SetPlayBackEndCallBack@8");
+        map.put("NS_NET_SetPlayBackPos", "_NS_NET_SetPlayBackPos@8");
+        map.put("NS_NET_SetSmartBoxConfig", "_NS_NET_SetSmartBoxConfig@8");
+        map.put("NS_NET_SetTargetLibraryManagementInfo", "_NS_NET_SetTargetLibraryManagementInfo@8");
+        map.put("NS_NET_SetTimePlayBackPos", "_NS_NET_SetTimePlayBackPos@8");
+        map.put("NS_NET_SetVolume", "_NS_NET_SetVolume@8");
+        map.put("NS_NET_SetWisdomPlatConfigInfo", "_NS_NET_SetWisdomPlatConfigInfo@8");
+        map.put("NS_NET_ShutDown", "_NS_NET_ShutDown@4");
+        map.put("NS_NET_StartPlayBack_Proxy", "_NS_NET_StartPlayBack_Proxy@84");
+        map.put("NS_NET_StartPlayBack_Trans", "_NS_NET_StartPlayBack_Trans@84");
+        map.put("NS_NET_StartProxyServer", "_NS_NET_StartProxyServer@20");
+        map.put("NS_NET_StartQueryOldPeopleStatuInfo", "_NS_NET_StartQueryOldPeopleStatuInfo@8");
+        map.put("NS_NET_StartTalkProxy", "_NS_NET_StartTalkProxy@40");
+        map.put("NS_NET_StartTrans_Proxy", "_NS_NET_StartTrans_Proxy@64");
+        map.put("NS_NET_StopMixAISubscription", "_NS_NET_StopMixAISubscription@4");
+        map.put("NS_NET_StopPlayBack_Proxy", "_NS_NET_StopPlayBack_Proxy@4");
+        map.put("NS_NET_StopPlayBack_Trans", "_NS_NET_StopPlayBack_Trans@4");
+        map.put("NS_NET_StopTalkProxy", "_NS_NET_StopTalkProxy@8");
+        map.put("NS_NET_StopTrans_Proxy", "_NS_NET_StopTrans_Proxy@4");
+        map.put("NS_NET_TalkStart", "_NS_NET_TalkStart@20");
+        map.put("NS_NET_TalkStop", "_NS_NET_TalkStop@4");
+        map.put("NS_NET_UnlockDisk", "_NS_NET_UnlockDisk@8");
+        map.put("NS_NET_Upgrade59ADeviceInfo", "_NS_NET_Upgrade59ADeviceInfo@8");
+        map.put("NS_NET_UpgradeStart", "_NS_NET_UpgradeStart@8");
+        map.put("NS_NET_UpgradeStop", "_NS_NET_UpgradeStop@4");
+        map.put("NS_NET_VideoTranspondStart", "_NS_NET_VideoTranspondStart@20");
+        map.put("NS_NET_VideoTranspondStartWithoutViskhead", "_NS_NET_VideoTranspondStartWithoutViskhead@20");
+        map.put("NS_NET_VideoTranspondStop", "_NS_NET_VideoTranspondStop@4");
+        map.put("NS_SetMsPreStreamChl", "_NS_SetMsPreStreamChl@12");
+        map.put("VSK_NET_FormatDiskByDiskNo", "_VSK_NET_FormatDiskByDiskNo@8");
+        map.put("VSK_NET_GetFormatDiskPrecentByDiskNo", "_VSK_NET_GetFormatDiskPrecentByDiskNo@12");
+        map.put("VSK_NET_SetAlarmOut", "_VSK_NET_SetAlarmOut@12");
+        map.put("VSK_NET_StartSearch", "_VSK_NET_StartSearch@4");
+        map.put("VSK_NET_StopSearch", "_VSK_NET_StopSearch@0");
+        map.put("_NS_NET_GetNvrCloudStoreAccountConfig@16", "_NS_NET_GetNvrCloudStoreAccountConfig@16");
+        map.put("_NS_NET_GetNvrCloudStorePlatformConfig@8", "_NS_NET_GetNvrCloudStorePlatformConfig@8");
+        map.put("_NS_NET_GetNvrEncorderParam@16", "_NS_NET_GetNvrEncorderParam@16");
+        map.put("_NS_NET_GetNvrJsdianxinPlatformConfig@8", "_NS_NET_GetNvrJsdianxinPlatformConfig@8");
+        map.put("_NS_NET_InitLog@12", "_NS_NET_InitLog@12");
+        map.put("_NS_NET_QueryBannerPictureClose@4", "_NS_NET_QueryBannerPictureClose@4");
+        map.put("_NS_NET_QueryBannerPictureCount@12", "_NS_NET_QueryBannerPictureCount@12");
+        map.put("_NS_NET_QueryBannerPictureInfo@8", "_NS_NET_QueryBannerPictureInfo@8");
+        map.put("_NS_NET_QueryNextBannerPictureInfo@8", "_NS_NET_QueryNextBannerPictureInfo@8");
+        map.put("_NS_NET_QueryNextParabolicPictureInfo@8", "_NS_NET_QueryNextParabolicPictureInfo@8");
+        map.put("_NS_NET_QueryParabolicPictureClose@4", "_NS_NET_QueryParabolicPictureClose@4");
+        map.put("_NS_NET_QueryParabolicPictureCount@12", "_NS_NET_QueryParabolicPictureCount@12");
+        map.put("_NS_NET_QueryParabolicPictureInfo@8", "_NS_NET_QueryParabolicPictureInfo@8");
+        map.put("_NS_NET_SendTalkData@16", "_NS_NET_SendTalkData@16");
+        map.put("_NS_NET_SetNvrCloudStoreAccountConfig@8", "_NS_NET_SetNvrCloudStoreAccountConfig@8");
+        map.put("_NS_NET_SetNvrCloudStorePlatformConfig@8", "_NS_NET_SetNvrCloudStorePlatformConfig@8");
+        map.put("_NS_NET_SetNvrEncorderParam@8", "_NS_NET_SetNvrEncorderParam@8");
+        map.put("_NS_NET_SetNvrJsdianxinPlatformConfig@8", "_NS_NET_SetNvrJsdianxinPlatformConfig@8");
+        map.put("_NS_NET_StopProxyServer@0", "_NS_NET_StopProxyServer@0");
+        map.put("_NS_NET_StopTalk@8", "_NS_NET_StopTalk@8");
+        map.put("_NS_NET_TalkStartEx@24", "_NS_NET_TalkStartEx@24");
+    }
+
+    /**
+     * 根据函数名取其在dll中的名称
+     *
+     * @param   library         库
+     * @param   method          该当
+     * @return  返回在动态库中的名称
+     */
+    @Override
+    public String getFunctionName(NativeLibrary library, Method method) {
+        String name = map.get(method.getName());
+        return name == null ? method.getName() : name;
+    }
+    
+}

+ 53 - 0
src/main/java/com/persagy/vsknet/Test.java

@@ -0,0 +1,53 @@
+package com.persagy.vsknet;
+
+import com.persagy.cameractl.conf.NVR9Config;
+import com.sun.jna.Native;
+import com.sun.jna.platform.win32.WinDef;
+import com.sun.jna.platform.win32.WinDef.UINT;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月29日 下午6:08:53
+ */
+public class Test {
+
+	public static void main(String[] args) {
+		// SDK 初始化
+		String windowsDllPath = NVR9Config.getWindowsDllPath(NVR9Config.NSDEVNET_DLL);
+		VskDevNet client = (VskDevNet) Native.load(windowsDllPath, VskDevNet.class);
+		Boolean initate = client.NS_NET_Initate();
+		System.out.println("SDK init: " + (initate == null ? false : initate));
+		
+		// API测试
+		test(client);
+		
+	}
+
+	/**
+	 * 测试API调用
+	 * 
+	 * @param client
+	 * @date 2021年9月29日 下午8:00:07
+	 */
+	private static void test(VskDevNet client) {
+		// 登录
+		UINT login = client.NS_NET_Login("ip".getBytes(), new WinDef.WORD(8000L), "admin".getBytes(), "password".getBytes(), null, null);
+		long userId = login == null ? -1L : login.longValue();
+		System.out.println("登录结果:" + userId);
+		
+		if (userId > 0) {
+			// 注销登录
+			Boolean logout = client.NS_NET_Logout(new UINT(userId));
+			System.out.println("注销登录:" + (logout == null ? false : logout));
+			
+			// 清除SDK
+			Boolean clear = client.NS_NET_Clear();
+			System.out.println("清除SDK:" + (clear == null ? false : clear));
+		}
+		
+	}
+	
+}

Datei-Diff unterdrückt, da er zu groß ist
+ 2281 - 0
src/main/java/com/persagy/vsknet/VskDevNet.java


+ 31 - 0
src/main/java/com/persagy/vsknet/a59/NETS_59A_LIBRARY_INFO.java

@@ -0,0 +1,31 @@
+package com.persagy.vsknet.a59;
+
+import com.sun.jna.Structure;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author 庞利祥 (sybotan@126.com)
+ */
+public class NETS_59A_LIBRARY_INFO extends Structure {
+	public int YawFaceAngle; // 偏航角(0-90)
+	public int PitchFaceAngle; // 俯仰角(0-90)
+	public int RollFaceAngle; // 翻滚角(0-90)
+	public int ClarifyThld; // 清晰度阀值(0-100)
+	public int MinObjectSize; // 最小目标尺寸(0-128)
+	public byte[] reserve = new byte[512];
+
+	public static class ByReference extends NETS_59A_LIBRARY_INFO implements Structure.ByReference {
+	}
+
+	public static class ByValue extends NETS_59A_LIBRARY_INFO implements Structure.ByValue {
+	}
+
+	@Override
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("YawFaceAngle", "PitchFaceAngle", "RollFaceAngle", "ClarifyThld", "MinObjectSize",
+				"reserve");
+	}
+
+}

+ 28 - 0
src/main/java/com/persagy/vsknet/a59/NETS_59A_UPGRADE_DEVICE_FILE.java

@@ -0,0 +1,28 @@
+package com.persagy.vsknet.a59;
+
+import com.sun.jna.Structure;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author 庞利祥 (sybotan@126.com)
+ */
+public class NETS_59A_UPGRADE_DEVICE_FILE extends Structure {
+
+	public int file_size; // 此文件很小,直接通过下面的file_data传递, 具体大小由此参数设置
+	public byte[] file_data = new byte[512];
+	public byte[] reserve = new byte[512];
+
+	public static class ByReference extends NETS_59A_UPGRADE_DEVICE_FILE implements Structure.ByReference {
+	}
+
+	public static class ByValue extends NETS_59A_UPGRADE_DEVICE_FILE implements Structure.ByValue {
+	}
+
+	@Override
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("file_size", "file_data", "reserve");
+	}
+	
+}

+ 33 - 0
src/main/java/com/persagy/vsknet/a59/NETS_59A_VERSION.java

@@ -0,0 +1,33 @@
+package com.persagy.vsknet.a59;
+
+import com.sun.jna.Structure;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author 庞利祥 (sybotan@126.com)
+ */
+public class NETS_59A_VERSION extends Structure {
+
+	public byte[] kernel = new byte[128];
+	public byte[] rootfs = new byte[128];
+	public byte[] version = new byte[128]; // 版本信息
+	public byte[] devicename = new byte[128];
+	public int ver; // 后面拓展的参数,如果值为0xABCD则判断num数量,使用info中的后缀进行升级
+	public int num;
+	public byte[][] info = new byte[6][20];
+	public byte[] reserve = new byte[384];
+
+	public static class ByReference extends NETS_59A_VERSION implements Structure.ByReference {
+	}
+
+	public static class ByValue extends NETS_59A_VERSION implements Structure.ByValue {
+	}
+
+	@Override
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("kernel", "rootfs", "version", "devicename", "ver", "num", "info", "reserve");
+	}
+
+}

+ 49 - 0
src/main/java/com/persagy/vsknet/enums/IPC_MACHINE_TYPE.java

@@ -0,0 +1,49 @@
+package com.persagy.vsknet.enums;
+
+public class IPC_MACHINE_TYPE {
+	public static final int ONVIF_PROTOCOL = 0x00; // ONVIF 0x00
+	public static final int ONVIF_LOCALTIME = 0x01; // Reserved
+	public static final int HHIPC = 0x02; // Huanghe IPC
+	public static final int RUISHI = 0x03; // RUISHI
+	public static final int RTSP_BASLER = 0x04;// Basler
+	public static final int RTSP_CUSTOM = 0x05;// Standard RTSP
+	public static final int RTSP_TURUIW = 0x06; // Tu rui wang
+	public static final int RTSP_SAMSUNG = 0x07; // Samsung
+	public static final int PROT_NSV = 0x08; // NewSeaUnion
+	public static final int PROT_HIKVISION = 0x09;// Hikvision
+	public static final int PROT_DAHUA = 0x0a; // Dahua
+	public static final int PROT_AIPSTAR = 0x0b;// Aipstar
+	public static final int PROT_HIKTRAFIC = 0x0c;// Hikvision Traffic
+	public static final int PROT_DYNACOLOR = 0x0d; // DynaColor
+	public static final int ONVIF_AXIS = 0x0e;
+	public static final int PROT_SONY = 0x0f;
+
+	public static final int MONITOR_IPC = 0x10; // Test Stream. 0x10
+	public static final int TIANGONG_RS = 0x11;// oem ruishi// TianGong
+	public static final int RTSP_DHL_TRW = 0x12;// DHL
+	public static final int PROT_ARECONT = 0x13; // Arecont
+	public static final int PROT_ARECONTSG = 0x14;// Other Arecont Device
+	public static final int PROT_OEM_RS = 0x15;
+	public static final int VSK_TS_PROTO = 0x16;// Visking Transpot Stream, VSK DVR,HMS
+	public static final int PROT_NEEDTEK = 0x17;// NeedTek
+	public static final int PROT_XILIAN = 0x18;// XIlian
+	public static final int PROT_TIANSHITONG = 0x19;// TianShiTong
+	public static final int PROT_SHENTONG = 0x1a;// ShenTong
+	public static final int PROT_HIXIN = 0x1b;// xilian.
+	public static final int PROT_YFT = 0x1c; // yingfeituo
+	public static final int PROT_MAIRUID = 0xd;// mai rui dian,shanghaidianqi encoder h264
+	public static final int PROT_SHENTMC = 0x1e;// shengtong multicast stream protocol. shanghaidianqi encoder mpeg2
+
+	public static final int MS_STREAM = 0x20; // Stream from Media Server 0x20
+	public static final int CLT_STREAM = 0x21;// stream from client Server
+	public static final int GB28181_STREAM = 0x22;// stream for 28181
+	public static final int VSK_LS_PROTO = 0x23;// visking proto
+	public static final int ONVIF_SSC_AXIS = 0x24;
+	public static final int PROT_SHENTONGUDP = 0x25;
+	public static final int PROT_HANKVISION = 0x26;
+
+	public static final int PROT_JIGUANG = 0x2a;// jiguang MZM-OC 0x2A
+	// 扩展定义
+	public static final int MAX_SUPPORTED_IPC = 0x2b;
+	// add other ipc here
+}

+ 43 - 0
src/main/java/com/persagy/vsknet/net/NETUSER_INFO_64.java

@@ -0,0 +1,43 @@
+package com.persagy.vsknet.net;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.persagy.vsknet.tmp.CONNECT_INFO;
+import com.persagy.vsknet.tmp.LOGIN_INFO;
+import com.persagy.vsknet.tmp.USER_PRIVILEGE_64;
+import com.sun.jna.Structure;
+import com.sun.jna.platform.win32.WinDef;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class NETUSER_INFO_64 extends Structure {
+
+    public WinDef.UINT user_id;
+    public WinDef.SHORT is_suspend;
+    public WinDef.SHORT last_time;
+    public LOGIN_INFO login_info;
+    public USER_PRIVILEGE_64 user_privilege;
+    public CONNECT_INFO main_con;
+    public CONNECT_INFO talk_con;
+    public CONNECT_INFO upgrade_con;
+    public CONNECT_INFO[] playback_con = new CONNECT_INFO[4];
+
+    public static class ByReference extends NETUSER_INFO_64 implements Structure.ByReference {}
+    public static class ByValue extends NETUSER_INFO_64 implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("user_id",
+                "is_suspend",
+                "last_time",
+                "login_info",
+                "user_privilege",
+                "main_con",
+                "talk_con",
+                "upgrade_con",
+                "playback_con");
+    }
+    
+}

+ 23 - 0
src/main/java/com/persagy/vsknet/net/NETUSER_LIST.java

@@ -0,0 +1,23 @@
+package com.persagy.vsknet.net;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class NETUSER_LIST extends Structure {
+
+    public NETUSER_INFO_64[] NetUserInfo = new NETUSER_INFO_64[10];
+
+    public static class ByReference extends NETUSER_LIST implements Structure.ByReference {}
+    public static class ByValue extends NETUSER_LIST implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("NetUserInfo");
+    }
+    
+}

+ 29 - 0
src/main/java/com/persagy/vsknet/net/NET_REPLY.java

@@ -0,0 +1,29 @@
+package com.persagy.vsknet.net;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.persagy.vsknet.tmp.PACKET_HEADER;
+import com.sun.jna.Structure;
+import com.sun.jna.platform.win32.WinDef;
+
+/**
+ * @author 庞利祥 (sybotan@126.com)
+ */
+public class NET_REPLY extends Structure {
+
+	public PACKET_HEADER header;
+	public WinDef.UINT ret_code;
+
+	public static class ByReference extends NET_REPLY implements Structure.ByReference {
+	}
+
+	public static class ByValue extends NET_REPLY implements Structure.ByValue {
+	}
+
+	@Override
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("header", "ret_code");
+	}
+
+}

+ 45 - 0
src/main/java/com/persagy/vsknet/net/NET_USER_INFO_REQ.java

@@ -0,0 +1,45 @@
+package com.persagy.vsknet.net;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+
+/**
+ * @author 庞利祥 (sybotan@126.com)
+ */
+public class NET_USER_INFO_REQ extends Structure {
+
+	public int db_index; // 数据库的id号
+	public int id; // 数据库中的id >=0 修改 < 0 新增
+	public byte[] name = new byte[32];
+	public int card_type; // 证件类型, 默认为0
+	public byte[] cardid = new byte[64]; // 身份证号
+	public byte[] birthday = new byte[16];
+	public int sexid; // 性别: 0 男 1 女
+	public byte[] telnum = new byte[16];
+	public byte[] addr = new byte[128];
+	public byte[] nation = new byte[16]; // 民族
+	public int identf; // VSK_NETSDK_IdentityEnum
+	public byte[] department = new byte[32]; // 部门
+	public byte[] work_no = new byte[32]; // 工作证号
+	public byte[] card_validity = new byte[24]; // 身份证有效期
+	public byte[] native1 = new byte[64]; // 籍贯,新的变量代替原本的省和市
+	public byte[] personid = new byte[64];
+	public byte[] reserve = new byte[64];
+	public int pic_num;
+
+	public static class ByReference extends NET_USER_INFO_REQ implements Structure.ByReference {
+	}
+
+	public static class ByValue extends NET_USER_INFO_REQ implements Structure.ByValue {
+	}
+
+	@Override
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("db_index", "id", "name", "card_type", "cardid", "birthday", "sexid", "telnum", "addr",
+				"nation", "identf", "department", "work_no", "card_validity", "native", "personid", "reserve",
+				"pic_num");
+	}
+	
+}

+ 36 - 0
src/main/java/com/persagy/vsknet/net/NET_USER_PIC_INFO.java

@@ -0,0 +1,36 @@
+package com.persagy.vsknet.net;
+
+import com.persagy.vsknet.vsk.VSK_NETS_ADD_MOD_USER_INFO_REQ;
+import com.sun.jna.Structure;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author 庞利祥 (sybotan@126.com)
+ */
+public class NET_USER_PIC_INFO extends Structure {
+
+	public int pic_index; // 此用户的第几张图片, 客户端传过来, 如果某张图片添加失败,则会在返回的结构体里面对应位置置1
+	public int pic_flag; // 0 添加或修改 1保持不变
+	public int pic_id; // 查询到的图片id 保持不变时需要赋值
+	public int piclen; // 这张图片长度
+	public byte[] picpath = new byte[128]; // 此参数在修改用户信息时使用到: 逻辑如下
+	// 如果没有图片数据说明图片没有修改,直接使用原本路径的图片, 否者全部替换为新图片
+	// 59NVR在查询时会返回此参数, 经济型NVR没有此参数, 但是逻辑都一样
+	public int time; // 图片入库时间 修改时需要返回此参数
+	public int[] reserve = new int[31];
+	public byte[] picdata;
+
+	public static class ByReference extends VSK_NETS_ADD_MOD_USER_INFO_REQ implements Structure.ByReference {
+	}
+
+	public static class ByValue extends VSK_NETS_ADD_MOD_USER_INFO_REQ implements Structure.ByValue {
+	}
+
+	@Override
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("pic_index", "pic_flag", "pic_id", "piclen", "picpath", "time", "reserve", "picdata");
+	}
+	
+}

+ 31 - 0
src/main/java/com/persagy/vsknet/net/NetAiAlarmInfoResponse.java

@@ -0,0 +1,31 @@
+package com.persagy.vsknet.net;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class NetAiAlarmInfoResponse extends Structure {
+
+    public int similarity;     //相似度
+    public byte[] dataBase = new  byte[128]; //数据库名称
+    public byte[] facePath = new  byte[128]; //图片路径
+    public byte[] name = new byte[128];     //人员姓名
+    public byte[] reserve = new byte[128];  //预留
+
+    public static class ByReference extends NetAiAlarmInfoResponse implements Structure.ByReference {}
+    public static class ByValue extends NetAiAlarmInfoResponse implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("similarity",
+                "dataBase",
+                "facePath",
+                "name",
+                "reserve");
+    }
+    
+}

+ 27 - 0
src/main/java/com/persagy/vsknet/net/NetGetAIAlarmInfo.java

@@ -0,0 +1,27 @@
+package com.persagy.vsknet.net;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class NetGetAIAlarmInfo extends Structure {
+
+    public int DBIndex;        //数据库ID
+    public byte[] identy = new byte[64];    //证件编号
+    public byte[] reserve = new byte[64];   //预留
+
+    public static class ByReference extends NetGetAIAlarmInfo implements Structure.ByReference {}
+    public static class ByValue extends NetGetAIAlarmInfo implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("DBIndex",
+                "identy",
+                "reserve");
+    }
+    
+}

+ 27 - 0
src/main/java/com/persagy/vsknet/netsdk/NETSDK_AI_NET_ALARM_CONFIG_EXT.java

@@ -0,0 +1,27 @@
+package com.persagy.vsknet.netsdk;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+
+/**
+ * @author 庞利祥 (sybotan@126.com)
+ */
+public class NETSDK_AI_NET_ALARM_CONFIG_EXT extends Structure {
+
+	public byte[] areaCode = new byte[64];// MQTT区域编码
+	public byte[] reserve = new byte[192];
+
+	public static class ByReference extends NETSDK_AI_NET_ALARM_CONFIG_EXT implements Structure.ByReference {
+	}
+
+	public static class ByValue extends NETSDK_AI_NET_ALARM_CONFIG_EXT implements Structure.ByValue {
+	}
+
+	@Override
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("areaCode", "reserve");
+	}
+
+}

+ 27 - 0
src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_MixAIBaseConfig.java

@@ -0,0 +1,27 @@
+package com.persagy.vsknet.netsdk;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+
+/**
+ * @author 庞利祥 (sybotan@126.com)
+ */
+public class NETSDK_VSK_MixAIBaseConfig extends Structure {
+
+	public byte[] netsdk_vsk_serverip = new byte[32];
+	public byte[] netsdk_vsk_res = new byte[1024];
+
+	public static class ByReference extends NETSDK_VSK_MixAIBaseConfig implements Structure.ByReference {
+	}
+
+	public static class ByValue extends NETSDK_VSK_MixAIBaseConfig implements Structure.ByValue {
+	}
+
+	@Override
+	protected List<String> getFieldOrder() {
+		return Arrays.asList("netsdk_vsk_serverip", "netsdk_vsk_res");
+	}
+
+}

+ 40 - 0
src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_MixAIQueryMotorRequset.java

@@ -0,0 +1,40 @@
+package com.persagy.vsknet.netsdk;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+import com.sun.jna.platform.win32.WinDef;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class NETSDK_VSK_MixAIQueryMotorRequset extends Structure {
+
+    public int netsdk_vsk_deviceid;               //-1全部;>=0为通道号
+    public int netsdk_vsk_featureid;              //DATAFEATURE_NET, 用_PLATE_COM_NET
+    public WinDef.ULONG netsdk_vsk_starttime;         //开始时间
+    public WinDef.ULONG netsdk_vsk_endtime;           //结束时间
+    public int netsdk_vsk_type;                   //0 查小图     1 查大图 车牌不支持大小图一起查询
+    public NETSDK_VSK_NetAIMotorInfo netsdk_vsk_info;        //默认-1全部
+    public WinDef.UINT netsdk_vsk_limitnum;      //查询最大数量(内存控制 比如说查询 前1000条)
+    public WinDef.UINT netsdk_vsk_limitnumstart; //默认从0开始
+    public byte[] netsdk_vsk_res  = new byte[1024];
+
+    public static class ByReference extends NETSDK_VSK_MixAIQueryMotorRequset implements Structure.ByReference {}
+    public static class ByValue extends NETSDK_VSK_MixAIQueryMotorRequset implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("netsdk_vsk_deviceid",
+                "netsdk_vsk_featureid",
+                "netsdk_vsk_starttime",
+                "netsdk_vsk_endtime",
+                "netsdk_vsk_type",
+                "netsdk_vsk_info",
+                "netsdk_vsk_limitnum",
+                "netsdk_vsk_limitnumstart",
+                "netsdk_vsk_res");
+    }
+    
+}

+ 44 - 0
src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_MixAIQueryMotorResponse.java

@@ -0,0 +1,44 @@
+package com.persagy.vsknet.netsdk;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+import com.sun.jna.platform.win32.WinDef;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class NETSDK_VSK_MixAIQueryMotorResponse extends Structure {
+
+    public int netsdk_vsk_diskno;
+    public int netsdk_vsk_partno;
+    public WinDef.ULONG netsdk_vsk_fileid;
+    public WinDef.ULONG netsdk_vsk_filesize;
+    public WinDef.ULONG netsdk_vsk_scanefileid;
+    public int netsdk_vsk_scanefilesize;
+    public int netsdk_vsk_devid;
+    public byte[] netsdk_vsk_filepath = new byte[128];
+    public WinDef.ULONG netsdk_vsk_filecreatetime;
+    public NETSDK_VSK_NetAIMotorInfo netsdk_vsk_m_fileinfo;
+    public byte[] netsdk_vsk_res = new byte[256];
+
+    public static class ByReference extends NETSDK_VSK_MixAIQueryMotorResponse implements Structure.ByReference {}
+    public static class ByValue extends NETSDK_VSK_MixAIQueryMotorResponse implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("netsdk_vsk_diskno",
+                "netsdk_vsk_partno",
+                "netsdk_vsk_fileid",
+                "netsdk_vsk_filesize",
+                "netsdk_vsk_scanefileid",
+                "netsdk_vsk_scanefilesize",
+                "netsdk_vsk_devid",
+                "netsdk_vsk_filepath",
+                "netsdk_vsk_filecreatetime",
+                "netsdk_vsk_m_fileinfo",
+                "netsdk_vsk_res");
+    }
+    
+}

+ 40 - 0
src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_MixAIQueryNonMotorRequset.java

@@ -0,0 +1,40 @@
+package com.persagy.vsknet.netsdk;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+import com.sun.jna.platform.win32.WinDef;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class NETSDK_VSK_MixAIQueryNonMotorRequset extends Structure {
+
+    public int netsdk_vsk_deviceid;               //-1全部;>=0为通道号
+    public int netsdk_vsk_featureid;              //DATAFEATURE_NET,非机动车用_Non_Motor_Vehicle
+    public WinDef.ULONG netsdk_vsk_starttime;         //开始时间
+    public WinDef.ULONG netsdk_vsk_endtime;           //结束时间
+    public int netsdk_vsk_type;                   //-1 查全部的 0 查小图     1 查大图
+    public NETSDK_VSK_NetAINonMotorInfo netsdk_vsk_info;     //默认-1全部
+    public WinDef.UINT netsdk_vsk_limitnum;      //查询最大数量(内存控制 比如说查询 前1000条)
+    public WinDef.UINT netsdk_vsk_limitnumstart; //默认从0开始
+    public byte[] netsdk_vsk_res = new byte[1024];
+
+    public static class ByReference extends NETSDK_VSK_MixAIQueryNonMotorRequset implements Structure.ByReference {}
+    public static class ByValue extends NETSDK_VSK_MixAIQueryNonMotorRequset implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("netsdk_vsk_deviceid",
+                "netsdk_vsk_featureid",
+                "netsdk_vsk_starttime",
+                "netsdk_vsk_endtime",
+                "netsdk_vsk_type",
+                "netsdk_vsk_info",
+                "netsdk_vsk_limitnum",
+                "netsdk_vsk_limitnumstart",
+                "netsdk_vsk_res");
+    }
+    
+}

+ 44 - 0
src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_MixAIQueryNonMotorResponse.java

@@ -0,0 +1,44 @@
+package com.persagy.vsknet.netsdk;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+import com.sun.jna.platform.win32.WinDef;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class NETSDK_VSK_MixAIQueryNonMotorResponse extends Structure {
+
+    public int netsdk_vsk_diskno;
+    public int netsdk_vsk_partno;
+    public WinDef.ULONG netsdk_vsk_fileid;
+    public WinDef.ULONG netsdk_vsk_filesize;
+    public WinDef.ULONG netsdk_vsk_scanefileid;
+    public int netsdk_vsk_scanefilesize;
+    public int netsdk_vsk_devid;
+    public byte[] netsdk_vsk_filepath = new byte[128];
+    public WinDef.ULONG netsdk_vsk_filecreatetime;
+    public NETSDK_VSK_NetAINonMotorInfo netsdk_vsk_m_fileinfo;
+    public byte[] netsdk_vsk_res = new byte[256];
+
+    public static class ByReference extends NETSDK_VSK_MixAIQueryNonMotorResponse implements Structure.ByReference {}
+    public static class ByValue extends NETSDK_VSK_MixAIQueryNonMotorResponse implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("netsdk_vsk_diskno",
+                "netsdk_vsk_partno",
+                "netsdk_vsk_fileid",
+                "netsdk_vsk_filesize",
+                "netsdk_vsk_scanefileid",
+                "netsdk_vsk_scanefilesize",
+                "netsdk_vsk_devid",
+                "netsdk_vsk_filepath",
+                "netsdk_vsk_filecreatetime",
+                "netsdk_vsk_m_fileinfo",
+                "netsdk_vsk_res");
+    }
+    
+}

+ 40 - 0
src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_MixAIQueryPeopleRequset.java

@@ -0,0 +1,40 @@
+package com.persagy.vsknet.netsdk;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+import com.sun.jna.platform.win32.WinDef;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class NETSDK_VSK_MixAIQueryPeopleRequset extends Structure {
+
+    public int netsdk_vsk_deviceid;               //-1全部;>=0为通道号
+    public int netsdk_vsk_featureid;              //DATAFEATURE_NET,行人用_PEOPLE 9
+    public WinDef.ULONG netsdk_vsk_starttime;         //开始时间
+    public WinDef.ULONG netsdk_vsk_endtime;           //结束时间
+    public int netsdk_vsk_type;                   //-1 查全部的 0 查小图     1 查大图
+    public NETSDK_VSK_NetAIPeopleInfo netsdk_vsk_info;       //默认-1全部
+    public WinDef.UINT netsdk_vsk_limitnum;      //查询最大数量(内存控制 比如说查询 前1000条)
+    public WinDef.UINT netsdk_vsk_limitnumstart; //默认从0开始
+    public byte[] netsdk_vsk_res = new byte[1024];
+
+    public static class ByReference extends NETSDK_VSK_MixAIQueryPeopleRequset implements Structure.ByReference {}
+    public static class ByValue extends NETSDK_VSK_MixAIQueryPeopleRequset implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("netsdk_vsk_deviceid",
+                "netsdk_vsk_featureid",
+                "netsdk_vsk_starttime",
+                "netsdk_vsk_endtime",
+                "netsdk_vsk_type",
+                "netsdk_vsk_info",
+                "netsdk_vsk_limitnum",
+                "netsdk_vsk_limitnumstart",
+                "netsdk_vsk_res");
+    }
+    
+}

+ 45 - 0
src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_MixAIQueryPeopleResponse.java

@@ -0,0 +1,45 @@
+package com.persagy.vsknet.netsdk;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+import com.sun.jna.platform.win32.WinDef;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class NETSDK_VSK_MixAIQueryPeopleResponse extends Structure {
+
+    public int netsdk_vsk_diskno;
+    public int netsdk_vsk_partno;
+    public WinDef.ULONG netsdk_vsk_fileid;
+    public WinDef.ULONG netsdk_vsk_filesize;
+    public WinDef.ULONG netsdk_vsk_scanefileid;
+    public int netsdk_vsk_scanefilesize;
+    public int netsdk_vsk_devid;
+    public byte[] netsdk_vsk_filepath = new byte[128];
+    public WinDef.ULONG netsdk_vsk_filecreatetime;
+    public NETSDK_VSK_NetAIPeopleInfo netsdk_vsk_m_fileinfo;
+    public byte[] netsdk_vsk_res = new byte[256];
+
+    public static class ByReference extends NETSDK_VSK_MixAIQueryPeopleResponse implements Structure.ByReference {}
+    public static class ByValue extends NETSDK_VSK_MixAIQueryPeopleResponse implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("netsdk_vsk_diskno",
+                "netsdk_vsk_partno",
+                "netsdk_vsk_fileid",
+                "netsdk_vsk_filesize",
+                "netsdk_vsk_scanefileid",
+                "netsdk_vsk_scanefilesize",
+                "netsdk_vsk_devid",
+                "netsdk_vsk_filepath",
+                "netsdk_vsk_filecreatetime",
+                "netsdk_vsk_m_fileinfo",
+                "netsdk_vsk_res");
+    }
+    
+}
+

+ 83 - 0
src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_MixAISubscibeRequest.java

@@ -0,0 +1,83 @@
+package com.persagy.vsknet.netsdk;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+import com.sun.jna.platform.win32.WinDef;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class NETSDK_VSK_MixAISubscibeRequest extends Structure {
+
+    //注册客户端信息
+    public WinDef.UINT userid;        //设备登录ID
+    public WinDef.UINT devid;         //设备ID
+    public WinDef.UINT devip;         //设备IP
+    public WinDef.UINT devport;       //设备接收报警端口
+    //行人
+    public int ppl_enable;             //使能开关
+    public int ppl_image;              //-1 全部 0 小图 1 大图
+    public NETSDK_VSK_NetAIPeopleInfo ppl_info;
+    public byte[] ppl_res = new byte[512];
+    //机动车
+    public int mtr_enable;             //使能开关
+    public int mtr_image;              //-1 全部 0 小图 1 大图
+    public NETSDK_VSK_NetAIMotorInfo mtr_info;
+    public byte[] mtr_res = new byte[512];
+    //非机动车
+    public int nonm_enable;
+    public int nonm_image;             //-1 全部 0 小图 1 大图
+    NETSDK_VSK_NetAINonMotorInfo nonm_info;
+    //背包,物品
+    public int bag_enable;
+    public int bag_image;              //-1 全部 0 小图 1 大图
+    public NETSDK_VSK_NetAIBagLeaveInfo bag_info;
+    public byte[] eventType = new byte[64];         //all全部 wireCross越线侦测 intrusion区域入侵 loitering徘徊检测 abandonedObjectDetection物品遗留 removObject物品遗失
+    public byte[] bag_res = new byte[64];
+    //高空抛物
+    public int paraboloid_enable;
+    public int paraboloid_image;       //-1 全部 0 小图 1 大图
+    public NETSDK_VSK_NetAIParaBoloidInfo boloid_info;
+    //横幅检测
+    public int banner_enable;
+    public int banner_image;           //-1 全部 0 小图 1 大图
+    public NETSDK_VSK_NetAIBannerInfo banner_info;
+    public byte[] surplus_res = new byte[104];
+
+    public static class ByReference extends NETSDK_VSK_MixAISubscibeRequest implements Structure.ByReference {}
+    public static class ByValue extends NETSDK_VSK_MixAISubscibeRequest implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("userid",
+                "devid",
+                "devip",
+                "devport",
+                "ppl_enable",
+                "ppl_image",
+                "ppl_info",
+                "ppl_res",
+                "mtr_enable",
+                "mtr_image",
+                "mtr_info",
+                "mtr_res",
+                "nonm_enable",
+                "nonm_image",
+                "nonm_info",
+                "bag_enable",
+                "bag_image",
+                "bag_info",
+                "eventType",
+                "bag_res",
+                "paraboloid_enable",
+                "paraboloid_image",
+                "boloid_info",
+                "banner_enable",
+                "banner_image",
+                "banner_info",
+                "surplus_res");
+    }
+    
+}

+ 36 - 0
src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_MixAISubscibeResponseHeader.java

@@ -0,0 +1,36 @@
+package com.persagy.vsknet.netsdk;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+import com.sun.jna.platform.win32.WinDef;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class NETSDK_VSK_MixAISubscibeResponseHeader extends Structure {
+
+    public int netsdk_vsk_cmd;                    //订阅命令号730
+    public int netsdk_vsk_channel;                //通道号0开始
+    public WinDef.ULONG netsdk_vsk_time;              //时间
+    public int netsdk_vsk_type;                   //类型:0人行 1机动车 2非机动车 4 高空抛物 5 横幅检测
+    public int netsdk_vsk_size;                   //下面数据的总大小
+    public int netsdk_vsk_smallimagesize;         //小图数据大小
+    public int netsdk_vsk_bigimagesize;           //大图数据大小
+
+    public static class ByReference extends NETSDK_VSK_MixAISubscibeResponseHeader implements Structure.ByReference {}
+    public static class ByValue extends NETSDK_VSK_MixAISubscibeResponseHeader implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("netsdk_vsk_cmd",
+                "netsdk_vsk_channel",
+                "netsdk_vsk_time",
+                "netsdk_vsk_type",
+                "netsdk_vsk_size",
+                "netsdk_vsk_smallimagesize",
+                "netsdk_vsk_bigimagesize");
+    }
+    
+}

+ 24 - 0
src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_NetAIBagLeaveInfo.java

@@ -0,0 +1,24 @@
+package com.persagy.vsknet.netsdk;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class NETSDK_VSK_NetAIBagLeaveInfo extends Structure {
+
+    public byte[] enevtType = new byte[64];
+    public byte[] ip = new byte[16];
+
+    public static class ByReference extends NETSDK_VSK_NetAIBagLeaveInfo implements Structure.ByReference {}
+    public static class ByValue extends NETSDK_VSK_NetAIBagLeaveInfo implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("enevtType", "ip");
+    }
+    
+}

+ 24 - 0
src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_NetAIBannerInfo.java

@@ -0,0 +1,24 @@
+package com.persagy.vsknet.netsdk;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class NETSDK_VSK_NetAIBannerInfo extends Structure {
+
+    public byte[] ip = new byte[16];
+    public byte[] res = new byte[48];
+
+    public static class ByReference extends NETSDK_VSK_NetAIBannerInfo implements Structure.ByReference {}
+    public static class ByValue extends NETSDK_VSK_NetAIBannerInfo implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("ip", "res");
+    }
+    
+}

+ 59 - 0
src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_NetAIMotorInfo.java

@@ -0,0 +1,59 @@
+package com.persagy.vsknet.netsdk;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class NETSDK_VSK_NetAIMotorInfo extends Structure {
+
+    public byte[] netsdk_vsk_numplate = new byte[16];          //车牌号
+    public byte[] netsdk_vsk_logoname = new byte[20];          //主品牌型号
+    public byte[] netsdk_vsk_sublogoname = new byte[20];       //子品牌型号 (未实现)
+    public int netsdk_vsk_carcolor;               //车身颜色
+    public int netsdk_vsk_cartype;                //车辆类型
+    public int netsdk_vsk_platecolor;             //车牌颜色
+    public int netsdk_vsk_platetype;              //车牌种类
+    public int netsdk_vsk_mainbelt;               //主安全带 (未实现)
+    public int netsdk_vsk_subbelt;                //副安全带 (未实现)
+    public int netsdk_vsk_sunroof;                //天窗 (未实现)
+    public int netsdk_vsk_sparetire;              //备胎 (未实现)
+    public int netsdk_vsk_rack;                   //行李架 (未实现)
+    public int netsdk_vsk_call;                   //打电话 (未实现)
+    public int netsdk_vsk_crash;                  //车辆撞损 (未实现)
+    public int netsdk_vsk_danger;                 //危化品车辆 (未实现)
+    public int netsdk_vsk_orientation;            //车辆的朝向
+    public byte[] eventType = new byte[64];
+    public byte[] ip = new byte[16];
+    public byte[] res = new byte[48];
+
+    public static class ByReference extends NETSDK_VSK_NetAIMotorInfo implements Structure.ByReference {}
+    public static class ByValue extends NETSDK_VSK_NetAIMotorInfo implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("netsdk_vsk_numplate",
+                "netsdk_vsk_logoname",
+                "netsdk_vsk_sublogoname",
+                "netsdk_vsk_carcolor",
+                "netsdk_vsk_cartype",
+                "netsdk_vsk_platecolor",
+                "netsdk_vsk_platetype",
+                "netsdk_vsk_mainbelt",
+                "netsdk_vsk_subbelt",
+                "netsdk_vsk_sunroof",
+                "netsdk_vsk_sparetire",
+                "netsdk_vsk_rack",
+                "netsdk_vsk_call",
+                "netsdk_vsk_crash",
+                "netsdk_vsk_danger",
+                "netsdk_vsk_orientation",
+                "eventType",
+                "ip",
+                "res");
+    }
+    
+}

+ 41 - 0
src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_NetAINonMotorInfo.java

@@ -0,0 +1,41 @@
+package com.persagy.vsknet.netsdk;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class NETSDK_VSK_NetAINonMotorInfo extends Structure {
+
+    public int parasol;                //加装伞具
+    public int helmet;                 //安全帽
+    public int overload;               //超载
+    public int retrograde;             //逆行
+    public int violatetrafficlight;    //违反交通灯信号
+    public int nonVehicleType;   // -1  NonMontorVehicleType_VK
+    public int orientation;            //非机动车的朝向
+    public byte[] eventType = new byte[64];
+    public byte[] ip = new byte[16];
+    public byte[] res = new byte[48];
+
+    public static class ByReference extends NETSDK_VSK_NetAIMotorInfo implements Structure.ByReference {}
+    public static class ByValue extends NETSDK_VSK_NetAIMotorInfo implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("parasol",
+                "helmet",
+                "overload",
+                "retrograde",
+                "violatetrafficlight",
+                "nonVehicleType",
+                "orientation",
+                "eventType",
+                "ip",
+                "res");
+    }
+    
+}

+ 24 - 0
src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_NetAIParaBoloidInfo.java

@@ -0,0 +1,24 @@
+package com.persagy.vsknet.netsdk;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class NETSDK_VSK_NetAIParaBoloidInfo extends Structure {
+
+    public byte[] ip = new byte[16];
+    public byte[] res = new byte[48];
+
+    public static class ByReference extends NETSDK_VSK_NetAIParaBoloidInfo implements Structure.ByReference {}
+    public static class ByValue extends NETSDK_VSK_NetAIParaBoloidInfo implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("ip", "res");
+    }
+    
+}

+ 59 - 0
src/main/java/com/persagy/vsknet/netsdk/NETSDK_VSK_NetAIPeopleInfo.java

@@ -0,0 +1,59 @@
+package com.persagy.vsknet.netsdk;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class NETSDK_VSK_NetAIPeopleInfo extends Structure {
+
+    public int netsdk_vsk_sex;                    //性别
+    public int netsdk_vsk_age;                    //年龄NETSDK_VSK_infi_age
+    public int netsdk_vsk_uppertype;                //上衣款式
+    public int netsdk_vsk_uppercolor;             //上衣颜色
+    public int netsdk_vsk_bottomtype;             //下衣款式
+    public int netsdk_vsk_bottomcolor;            //下衣颜色
+    public int netsdk_vsk_glass;                    //眼镜
+    public int netsdk_vsk_hat;                    //帽子
+    public int netsdk_vsk_baby;                    //抱小孩
+    public int netsdk_vsk_bag;                    //拎东西
+    public int netsdk_vsk_knapsack;                //背包
+    public int netsdk_vsk_umbrella;                //打伞
+    public int netsdk_vsk_orientation;            //人的朝向
+    public int netsdk_vsk_shoulderbag;            //单肩包
+    public int helmet;                 //安全帽
+    public int fluorescentsuit;        //荧光服
+    public byte[] eventType = new byte[64];
+    public byte[] ip = new byte[16];
+    public byte[] res = new byte[48];
+
+    public static class ByReference extends NETSDK_VSK_NetAIPeopleInfo implements Structure.ByReference {}
+    public static class ByValue extends NETSDK_VSK_NetAIPeopleInfo implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("netsdk_vsk_sex",
+                "netsdk_vsk_age",
+                "netsdk_vsk_uppertype",
+                "netsdk_vsk_uppercolor",
+                "netsdk_vsk_bottomtype",
+                "netsdk_vsk_bottomcolor",
+                "netsdk_vsk_glass",
+                "netsdk_vsk_hat",
+                "netsdk_vsk_baby",
+                "netsdk_vsk_bag",
+                "netsdk_vsk_knapsack",
+                "netsdk_vsk_umbrella",
+                "netsdk_vsk_orientation",
+                "netsdk_vsk_shoulderbag",
+                "helmet",
+                "fluorescentsuit",
+                "eventType",
+                "ip",
+                "res");
+    }
+    
+}

+ 42 - 0
src/main/java/com/persagy/vsknet/nvr/FNVR_SYS_INFO.java

@@ -0,0 +1,42 @@
+package com.persagy.vsknet.nvr;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+import com.sun.jna.platform.win32.WinDef;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class FNVR_SYS_INFO extends Structure {
+
+    public byte video_chns;			/*IP Video channels*/
+    public byte audio_chns;			/*Audio channel number*/
+    public byte alarmin_chns;		/*Alarm input channel number*/
+    public byte alarmout_chns;		/*Alarm output channel number*/
+    public byte serial_num;			/*Number of external serial ports (excluding debugging serial ports and front panel serial ports)*/
+    public byte dec_pic_size;		/*Maximum decoding resolution supported by the device DECODE_SIZE_D1...*/
+    public WinDef.USHORT vga_resolution; 		/*VGA supported resolution,bitmap bit0: PIXEL_720P60  bit1: PIXEL_1080P50  ...*/
+    public WinDef.UINT version;			/*Software version number*/
+    public byte[] reserved = new byte[12];
+    public byte[] release_date = new byte[32];	/*The release date*/
+
+    public static class ByReference extends FNVR_SYS_INFO implements Structure.ByReference {}
+    public static class ByValue extends FNVR_SYS_INFO implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("video_chns",
+                "audio_chns",
+                "alarmin_chns",
+                "alarmout_chns",
+                "serial_num",
+                "dec_pic_size",
+                "vga_resolution",
+                "version",
+                "reserved",
+                "release_date");
+    }
+    
+}

+ 24 - 0
src/main/java/com/persagy/vsknet/nvr/FNVR_SYS_INFO_DSP.java

@@ -0,0 +1,24 @@
+package com.persagy.vsknet.nvr;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+import com.sun.jna.platform.win32.WinDef;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class FNVR_SYS_INFO_DSP extends Structure {
+
+    public WinDef.UINT dspversion;         /*DSP Driver software version number*/
+
+    public static class ByReference extends FNVR_SYS_INFO_DSP implements Structure.ByReference {}
+    public static class ByValue extends FNVR_SYS_INFO_DSP implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("dspversion");
+    }
+    
+}

+ 27 - 0
src/main/java/com/persagy/vsknet/nvr/NVR_ALARM_INFO.java

@@ -0,0 +1,27 @@
+package com.persagy.vsknet.nvr;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.persagy.vsknet.net.NET_REPLY;
+import com.sun.jna.Structure;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class NVR_ALARM_INFO extends Structure {
+
+    public NET_REPLY reply;
+    public int type;	// 报警类型定义: EVENT_TYPE_ALARM_IN  ...
+    public int channel;
+    public byte[] IP = new byte[16];
+
+    public static class ByReference extends NVR_ALARM_INFO implements Structure.ByReference {}
+    public static class ByValue extends NVR_ALARM_INFO implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("reply", "type", "channel", "IP");
+    }
+    
+}

+ 26 - 0
src/main/java/com/persagy/vsknet/nvr/NVR_CHANNEL_GB_ID.java

@@ -0,0 +1,26 @@
+package com.persagy.vsknet.nvr;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+import com.sun.jna.platform.win32.WinDef;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class NVR_CHANNEL_GB_ID extends Structure {
+
+    public WinDef.USHORT chan;
+    public byte[] deviceid = new byte[21];
+    public byte[] reserv2 = new byte[105];
+
+    public static class ByReference extends NVR_CHANNEL_GB_ID implements Structure.ByReference {}
+    public static class ByValue extends NVR_CHANNEL_GB_ID implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("chan", "deviceid", "reserv2");
+    }
+    
+}

+ 48 - 0
src/main/java/com/persagy/vsknet/nvr/NVR_CHANNEL_PARA.java

@@ -0,0 +1,48 @@
+package com.persagy.vsknet.nvr;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.jna.Structure;
+import com.sun.jna.platform.win32.WinDef;
+
+/**
+ * @author  庞利祥 (sybotan@126.com)
+ */
+public class NVR_CHANNEL_PARA extends Structure {
+
+    public byte invalid;
+    public byte[] reserv = new byte[1];
+    public WinDef.USHORT chl;
+    public byte[] channame = new byte[64];
+    public byte[] deviceid = new byte[21];
+    public byte[] reserve1 = new byte[3];
+    public byte[] alarmid = new byte[20];
+    public byte identifying;    //通道标识   0 入口, 1 出口
+    public byte res256Ena;    //因为和上面冲突了,放到下个字节位,本来这个参数也是个假的逻辑参数
+    public byte[] reserv2 = new byte[2];
+    public float longitude;    //经度 2020-10-16号March特殊版本加的参数,直接修正,错乱就错乱了
+    public float latitude;        //纬度 2020-10-16号March特殊版本加的参数,直接修正
+    public byte[] reserv3 = new byte[8];
+
+    public static class ByReference extends NVR_CHANNEL_PARA implements Structure.ByReference {}
+    public static class ByValue extends NVR_CHANNEL_PARA implements Structure.ByValue {}
+
+    @Override
+    protected List<String> getFieldOrder() {
+        return Arrays.asList("invalid",
+                "reserv",
+                "chl",
+                "channame",
+                "deviceid",
+                "reserve1",
+                "alarmid",
+                "identifying",
+                "res256Ena",
+                "reserv2",
+                "longitude",
+                "latitude",
+                "reserv3");
+    }
+    
+}

+ 0 - 0
src/main/java/com/persagy/vsknet/nvr/NVR_DISK_INFO.java


Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.