zhangqiankun 2 lat temu
rodzic
commit
b8f6b21648
62 zmienionych plików z 23167 dodań i 1 usunięć
  1. BIN
      resourcesFile/cameraDll/windows/AudioRender.dll
  2. BIN
      resourcesFile/cameraDll/windows/EagleEyeRender.dll
  3. BIN
      resourcesFile/cameraDll/windows/GdiPlus.dll
  4. BIN
      resourcesFile/cameraDll/windows/HCCore.dll
  5. BIN
      resourcesFile/cameraDll/windows/HCNetSDK.dll
  6. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/AnalyzeData.dll
  7. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/AudioIntercom.dll
  8. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/AudioRender.dll
  9. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/HCAlarm.dll
  10. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/HCAlarm.lib
  11. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/HCCoreDevCfg.dll
  12. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/HCDisplay.dll
  13. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/HCGeneralCfgMgr.dll
  14. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/HCGeneralCfgMgr.lib
  15. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/HCIndustry.dll
  16. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/HCPlayBack.dll
  17. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/HCPreview.dll
  18. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/HCPreview.lib
  19. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/HCVoiceTalk.dll
  20. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/OpenAL32.dll
  21. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/StreamTransClient.dll
  22. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/SystemTransform.dll
  23. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/libiconv2.dll
  24. BIN
      resourcesFile/cameraDll/windows/HCNetSDKCom/msvcr90.dll
  25. BIN
      resourcesFile/cameraDll/windows/HXVA.dll
  26. BIN
      resourcesFile/cameraDll/windows/HmMerge.dll
  27. BIN
      resourcesFile/cameraDll/windows/MP_Render.dll
  28. BIN
      resourcesFile/cameraDll/windows/MP_VIE.dll
  29. BIN
      resourcesFile/cameraDll/windows/NPQos.dll
  30. BIN
      resourcesFile/cameraDll/windows/OpenAL32.dll
  31. BIN
      resourcesFile/cameraDll/windows/PlayCtrl.dll
  32. BIN
      resourcesFile/cameraDll/windows/SuperRender.dll
  33. BIN
      resourcesFile/cameraDll/windows/YUVProcess.dll
  34. BIN
      resourcesFile/cameraDll/windows/gdiplus.dll
  35. BIN
      resourcesFile/cameraDll/windows/hlog.dll
  36. BIN
      resourcesFile/cameraDll/windows/hpr.dll
  37. BIN
      resourcesFile/cameraDll/windows/libcrypto-1_1.dll
  38. BIN
      resourcesFile/cameraDll/windows/libeay32.dll
  39. BIN
      resourcesFile/cameraDll/windows/libmmd.dll
  40. BIN
      resourcesFile/cameraDll/windows/libssl-1_1.dll
  41. BIN
      resourcesFile/cameraDll/windows/ssleay32.dll
  42. BIN
      resourcesFile/cameraDll/windows/zlib1.dll
  43. 39 0
      src/main/java/com/persagy/cameractl/controller/RemoteConfigCallBack.java
  44. 63 0
      src/main/java/com/persagy/cameractl/controller/RemoteConfigTask.java
  45. 156 0
      src/main/java/com/persagy/cameractl/controller/Test2Controller.java
  46. 53 0
      src/main/java/com/persagy/cameractl/sdk40/DownloadTask.java
  47. 10503 0
      src/main/java/com/persagy/cameractl/sdk40/HCNetSDK.java
  48. 242 0
      src/main/java/com/persagy/cameractl/sdk40/PlayBackController.java
  49. 333 0
      src/main/java/com/persagy/cameractl/sdk40/PlayBackEventController.java
  50. 46 0
      src/main/java/com/persagy/cameractl/sdk40/PlayDataCallBack.java
  51. 83 0
      src/main/java/com/persagy/cameractl/sdk40/PlaybackTask.java
  52. 205 0
      src/main/java/com/persagy/cameractl/temp/ClinetDemo.java
  53. 19 0
      src/main/java/com/persagy/cameractl/temp/CommonUtil.java
  54. 10503 0
      src/main/java/com/persagy/cameractl/temp/HCNetSDK.java
  55. 853 0
      src/main/java/com/persagy/cameractl/temp/VideoDemo.java
  56. 17 0
      src/main/java/com/persagy/cameractl/temp/osSelect.java
  57. 3 0
      src/main/java/com/persagy/cameractl/utils/Camera.java
  58. 19 0
      src/main/java/com/persagy/cameractl/utils/CommonUtil.java
  59. 6 0
      src/main/java/com/persagy/cameractl/utils/OtherTools.java
  60. 17 0
      src/main/java/com/persagy/cameractl/utils/osSelect.java
  61. 1 1
      src/main/resources/application.yml
  62. 6 0
      src/main/resources/camera.json

BIN
resourcesFile/cameraDll/windows/AudioRender.dll


BIN
resourcesFile/cameraDll/windows/EagleEyeRender.dll


BIN
resourcesFile/cameraDll/windows/GdiPlus.dll


BIN
resourcesFile/cameraDll/windows/HCCore.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDK.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/AnalyzeData.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/AudioIntercom.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/AudioRender.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/HCAlarm.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/HCAlarm.lib


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/HCCoreDevCfg.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/HCDisplay.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/HCGeneralCfgMgr.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/HCGeneralCfgMgr.lib


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/HCIndustry.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/HCPlayBack.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/HCPreview.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/HCPreview.lib


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/HCVoiceTalk.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/OpenAL32.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/StreamTransClient.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/SystemTransform.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/libiconv2.dll


BIN
resourcesFile/cameraDll/windows/HCNetSDKCom/msvcr90.dll


BIN
resourcesFile/cameraDll/windows/HXVA.dll


BIN
resourcesFile/cameraDll/windows/HmMerge.dll


BIN
resourcesFile/cameraDll/windows/MP_Render.dll


BIN
resourcesFile/cameraDll/windows/MP_VIE.dll


BIN
resourcesFile/cameraDll/windows/NPQos.dll


BIN
resourcesFile/cameraDll/windows/OpenAL32.dll


BIN
resourcesFile/cameraDll/windows/PlayCtrl.dll


BIN
resourcesFile/cameraDll/windows/SuperRender.dll


BIN
resourcesFile/cameraDll/windows/YUVProcess.dll


BIN
resourcesFile/cameraDll/windows/gdiplus.dll


BIN
resourcesFile/cameraDll/windows/hlog.dll


BIN
resourcesFile/cameraDll/windows/hpr.dll


BIN
resourcesFile/cameraDll/windows/libcrypto-1_1.dll


BIN
resourcesFile/cameraDll/windows/libeay32.dll


BIN
resourcesFile/cameraDll/windows/libmmd.dll


BIN
resourcesFile/cameraDll/windows/libssl-1_1.dll


BIN
resourcesFile/cameraDll/windows/ssleay32.dll


BIN
resourcesFile/cameraDll/windows/zlib1.dll


+ 39 - 0
src/main/java/com/persagy/cameractl/controller/RemoteConfigCallBack.java

@@ -0,0 +1,39 @@
+package com.persagy.cameractl.controller;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import com.persagy.cameractl.sdk40.HCNetSDK.FRemoteConfigCallBack;
+import com.sun.jna.Pointer;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2022年6月24日 下午12:48:42
+ */
+public class RemoteConfigCallBack implements FRemoteConfigCallBack {
+	
+	private FileOutputStream outputStream;
+	
+	public RemoteConfigCallBack(FileOutputStream outputStream) {
+		this.outputStream = outputStream;
+	}
+	
+	@Override
+	public void invoke(int dwType, Pointer lpBuffer, int dwBufLen, Pointer pUserData) {
+		long offset = 0;
+        ByteBuffer buffers = pUserData.getByteBuffer(offset, dwBufLen);
+        byte[] bytes = new byte[dwBufLen];
+        buffers.rewind();
+        buffers.get(bytes);
+        try {
+            outputStream.write(bytes);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+	}
+
+}

+ 63 - 0
src/main/java/com/persagy/cameractl/controller/RemoteConfigTask.java

@@ -0,0 +1,63 @@
+package com.persagy.cameractl.controller;
+
+import static com.persagy.cameractl.sdk40.PlayBackController.hCNetSDK;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 视频回放的定时器任务
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2022年6月23日 上午11:35:01
+ */
+public class RemoteConfigTask extends java.util.TimerTask {
+	public static Logger logger = LoggerFactory.getLogger(RemoteConfigTask.class);
+	
+	public volatile boolean endStatus = false;
+	
+	public volatile int startRemoteConfig;
+	
+	private FileOutputStream outputStream;
+	
+	public RemoteConfigTask (FileOutputStream outputStream, int startRemoteConfig) {
+		this.startRemoteConfig = startRemoteConfig;
+		this.outputStream = outputStream;
+	}
+	
+	@Override
+	public void run() {
+		logger.info("========= remoteConfigTask start =========");
+
+		int nextRemoteConfig = hCNetSDK.NET_DVR_GetNextRemoteConfig(startRemoteConfig, null, 0);
+		if (nextRemoteConfig < 0) {
+			logger.info("get all remoteConfig faliure, errorCode: " + hCNetSDK.NET_DVR_GetLastError());
+			endStatus = true;
+		}
+		
+		if (nextRemoteConfig == 1002) {
+			logger.info("get all remoteConfig success");
+			endStatus = true;
+		}
+		
+		if (nextRemoteConfig == 1003) {
+			logger.info("get all remoteConfig exception, errorCode: " + hCNetSDK.NET_DVR_GetLastError());
+			endStatus = true;
+		}
+
+		if (outputStream != null) {
+			try {
+				outputStream.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+		
+	}
+
+}

+ 156 - 0
src/main/java/com/persagy/cameractl/controller/Test2Controller.java

@@ -0,0 +1,156 @@
+package com.persagy.cameractl.controller;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.Timer;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+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.RestController;
+
+import com.persagy.cameractl.conf.CameraApiConfig;
+import com.persagy.cameractl.sdk40.HCNetSDK;
+import com.persagy.cameractl.sdk40.HCNetSDK.NET_DVR_USER_LOGIN_INFO;
+import com.persagy.cameractl.utils.Camera;
+import com.persagy.cameractl.utils.OtherTools;
+import com.persagy.cameractl.utils.ResultClass;
+import com.persagy.cameractl.utils.StringTools;
+
+/**
+ * 测试类
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2022年6月20日 下午5:43:10
+ */
+@RestController
+public class Test2Controller {
+	public static Logger logger = LoggerFactory.getLogger(Test2Controller.class);
+	
+	/** 项目根路径*/
+	public static final String SERVER_ROOT_PATH = System.getProperty("user.dir");
+	
+	public static volatile HCNetSDK hCNetSDK;
+	private volatile boolean isInit = false;
+	
+	@Autowired
+	private CameraApiConfig cameraApiConfig;
+	
+	@RequestMapping(value = "/sso", method = RequestMethod.POST)
+	public ResultClass hello(@RequestBody Camera camera) throws Exception {
+		ResultClass returnResult = new ResultClass();
+		returnResult.name = false;
+		
+		// SDK初始化
+		boolean init = this.init();
+		if (!init) {
+			returnResult.reason = "SDK初始化失败";
+			return returnResult;
+		}
+		
+		HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();//设备信息
+        NET_DVR_USER_LOGIN_INFO m_strLoginInfo = this.getLoginObject(cameraApiConfig.getDecodeDeviceUserName(), cameraApiConfig.getDecodeDevicePassword(), cameraApiConfig.getDecodeDeviceIp(), (short)cameraApiConfig.getDecodeDevicePort());
+        int lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
+        if (lUserID == -1) {
+        	int errCode = hCNetSDK.NET_DVR_GetLastError();
+        	returnResult.reason = "设备注册失败,失败码: " + errCode;
+			return returnResult;
+        }
+        
+        String targetFile = getVideoFilePath();
+		File file = new File(targetFile);
+		if (!file.exists()) {
+			file.createNewFile();
+		}
+        // 获取所有的流ID
+		FileOutputStream outputStream = new FileOutputStream(file);
+        RemoteConfigCallBack remoteConfigCallBack = new RemoteConfigCallBack(outputStream);
+        int startRemoteConfig = hCNetSDK.NET_DVR_StartRemoteConfig(lUserID, 6161, null, 0, remoteConfigCallBack, null);
+        if (startRemoteConfig <= -1) {
+			logger.warn("NET_DVR_StartRemoteConfig failure, errorCode: " + hCNetSDK.NET_DVR_GetLastError());
+			returnResult.reason = "启动远程配置失败,错误码: " + hCNetSDK.NET_DVR_GetLastError();
+			return returnResult;
+		}
+        
+        // 开始计时器,逐个获取查找到的信息
+ 		Timer remoteConfigTimer = new Timer();	// 新建定时器
+ 		RemoteConfigTask remoteConfigTask = new RemoteConfigTask(outputStream, startRemoteConfig);
+ 		remoteConfigTimer.schedule(remoteConfigTask, 0, 5000);	// 0秒后开始响应函数
+
+ 		while (!remoteConfigTask.endStatus) {
+ 			// 等待获取结束
+ 			try {
+ 				Thread.sleep(1000);
+ 			} catch (InterruptedException e) {
+ 				e.printStackTrace();
+ 			}
+ 		}
+     		
+        // 关闭资源
+        boolean remoteConfig = hCNetSDK.NET_DVR_StopRemoteConfig(startRemoteConfig);
+        if (!remoteConfig) {
+        	logger.warn("NET_DVR_StopRemoteConfig failure, errorCode: " + hCNetSDK.NET_DVR_GetLastError());
+			returnResult.reason = "关闭长连接配置接口所创建的句柄,释放资源失败,错误码: " + hCNetSDK.NET_DVR_GetLastError();
+			return returnResult;
+		}
+        
+        //退出程序时调用,每一台设备分别注销
+        if (hCNetSDK.NET_DVR_Logout(lUserID)) {
+            logger.info("logout success");
+        }
+        
+        returnResult.name = true;
+		return returnResult;
+	}
+	
+	
+	private boolean init() {
+		if (!isInit) {
+			// 初始化
+			hCNetSDK = HCNetSDK.INSTANCE;
+			isInit = hCNetSDK.NET_DVR_Init();
+		}
+		return isInit;
+	}
+	
+	private HCNetSDK.NET_DVR_USER_LOGIN_INFO getLoginObject(String m_sUsername, String m_sPassword, String m_sDeviceIP, short wPort) {
+		HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();//设备登录信息
+
+        m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
+        System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length());
+
+        m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
+        System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length());
+
+        m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
+        System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length());
+
+        m_strLoginInfo.wPort = wPort; //SDK端口
+        m_strLoginInfo.bUseAsynLogin = false; //是否异步登录:0- 否,1- 是
+        m_strLoginInfo.write();
+        
+        return m_strLoginInfo;
+	}
+	
+	public static String getVideoFilePath() {
+		String token = StringTools.getUUID();
+		return getVideoFilePathByT(token);
+	}
+
+	public static String getVideoFilePathByT(String token) {
+		try {
+			String playFileName = token + ".txt";
+			String playFileDir = OtherTools.getVideoFileDir();
+			return playFileDir + "/" + playFileName;
+		} catch (Exception e) {
+			logger.error(e.getMessage());
+			return "";
+		}
+	}
+
+}

+ 53 - 0
src/main/java/com/persagy/cameractl/sdk40/DownloadTask.java

@@ -0,0 +1,53 @@
+package com.persagy.cameractl.sdk40;
+
+import static com.persagy.cameractl.sdk40.PlayBackController.hCNetSDK;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.sun.jna.ptr.IntByReference;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2022年6月23日 下午1:47:59
+ */
+
+public class DownloadTask extends java.util.TimerTask {
+	public static Logger logger = LoggerFactory.getLogger(DownloadTask.class);
+
+	public volatile boolean endStatus = false;
+
+	public volatile int m_lLoadHandle;
+	
+	public DownloadTask (int m_lLoadHandle) {
+		this.m_lLoadHandle = m_lLoadHandle;
+	}
+	
+	@Override
+	public void run() {
+		logger.info("========= playback download Task start =========");
+
+		IntByReference nPos = new IntByReference(0);
+		if (!hCNetSDK.NET_DVR_PlayBackControl_V40(m_lLoadHandle, HCNetSDK.NET_DVR_PLAYGETPOS, null, 0,
+				nPos.getPointer(), new IntByReference(0))) {
+			endStatus = true;
+			logger.info("playback download faliure, errorCode: " + hCNetSDK.NET_DVR_GetLastError());
+		}
+
+		if (nPos.getValue() > 100) {
+			m_lLoadHandle = -1;
+			endStatus = true;
+			logger.info("playback download exception exit, errorCode: " + hCNetSDK.NET_DVR_GetLastError());
+		}
+
+		if (nPos.getValue() == 100) {
+			m_lLoadHandle = -1;
+			endStatus = true;
+			logger.info("playback download end exit");
+		}
+	}
+
+}

Plik diff jest za duży
+ 10503 - 0
src/main/java/com/persagy/cameractl/sdk40/HCNetSDK.java


+ 242 - 0
src/main/java/com/persagy/cameractl/sdk40/PlayBackController.java

@@ -0,0 +1,242 @@
+package com.persagy.cameractl.sdk40;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Timer;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+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.RestController;
+
+import com.persagy.cameractl.conf.CameraApiConfig;
+import com.persagy.cameractl.sdk40.HCNetSDK.NET_DVR_USER_LOGIN_INFO;
+import com.persagy.cameractl.sdk40.HCNetSDK.NET_DVR_VOD_PARA;
+import com.persagy.cameractl.utils.Camera;
+import com.persagy.cameractl.utils.OtherTools;
+import com.persagy.cameractl.utils.ResultClass;
+import com.sun.jna.Pointer;
+import com.sun.jna.ptr.IntByReference;
+
+import cn.hutool.core.date.DateUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2022年6月23日 上午11:12:34
+ */
+@RestController
+public class PlayBackController {
+	public static Logger logger = LoggerFactory.getLogger(PlayBackController.class);
+
+	public static volatile HCNetSDK hCNetSDK;
+	
+	private volatile boolean isInit = false;
+	
+	@Autowired
+	private CameraApiConfig cameraApiConfig;
+
+	@RequestMapping(value = "/playback/{operType}", method = RequestMethod.POST)
+	public ResultClass play(@RequestBody Camera camera, @PathVariable("operType") String operType) throws Exception {
+		ResultClass returnResult = new ResultClass();
+		returnResult.name = false;
+		
+		// SDK初始化
+		boolean init = this.init();
+		if (!init) {
+			returnResult.reason = "SDK初始化失败";
+			return returnResult;
+		}
+        
+        //登录设备,每一台设备分别登录; 登录句柄是唯一的,可以区分设备
+        HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();//设备信息
+        NET_DVR_USER_LOGIN_INFO m_strLoginInfo = this.getLoginObject(cameraApiConfig.getDecodeDeviceUserName(), cameraApiConfig.getDecodeDevicePassword(), cameraApiConfig.getDecodeDeviceIp(), (short)cameraApiConfig.getDecodeDevicePort());
+        int lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
+        if (lUserID == -1) {
+        	int errCode = hCNetSDK.NET_DVR_GetLastError();
+        	returnResult.reason = "设备注册失败,失败码: " + errCode;
+			return returnResult;
+        }
+        
+        logger.info(camera.cameraIp + ": login success! " + "device serial number: " + new String(m_strDeviceInfo.struDeviceV30.sSerialNumber).trim());
+        m_strDeviceInfo.read();
+        
+        //按时间回放和下载
+        String result = null;
+        String targetFile = OtherTools.getVideoFilePath();
+		File file = new File(targetFile);
+		if (!file.exists()) {
+			file.createNewFile();
+		}
+		if ("stream".equals(operType)) {
+			result = this.playBackBytime(file, camera.startDateStr, camera.endDateStr, lUserID, camera.streamId);
+		} else {
+			returnResult.reason = "非法请求";
+			return returnResult;
+		}
+        
+        //退出程序时调用,每一台设备分别注销
+        if (hCNetSDK.NET_DVR_Logout(lUserID)) {
+            logger.info("logout success");
+        }
+        
+        // SDK反初始化,释放资源,只需要退出时调用一次
+        // hCNetSDK.NET_DVR_Cleanup();
+		
+        if ("true".equals(result)) {
+        	returnResult.reason = "文件生成成功";
+        	Map<String, String> data = new HashMap<String, String>(4);
+			data.put("url", OtherTools.playMp4RootUrl + OtherTools.getMp4NamePrefix(file.getName()));
+			returnResult.resultData = data;
+		} else {
+			returnResult.reason = result;
+		}
+        
+        returnResult.name = true;
+		return returnResult;
+	}
+	
+	/**
+	 * 按时间回放获取码流数据
+	 * 
+	 * @param userID
+	 * @throws IOException 
+	 */
+	public String playBackBytime(File file, String startParam, String endParam, int userID, String streamId) throws IOException {
+		NET_DVR_VOD_PARA net_dvr_vod_para = getPlayBackHkTime(startParam, endParam, streamId);
+		int iPlayBack = hCNetSDK.NET_DVR_PlayBackByTime_V40(userID, net_dvr_vod_para);
+		if (iPlayBack <= -1) {
+			logger.warn("playback failure, errorCode: " + hCNetSDK.NET_DVR_GetLastError());
+			return "取流失败,失败码: " + hCNetSDK.NET_DVR_GetLastError();
+		}
+		
+		// 开启取流
+		if (!hCNetSDK.NET_DVR_PlayBackControl_V40(iPlayBack, HCNetSDK.NET_DVR_PLAYSTART, null, 0, null, new IntByReference(0))) {
+			logger.warn("NET_DVR_PlayBackControl_V40 failure, errorCode: " + hCNetSDK.NET_DVR_GetLastError());
+			return "取流失败,失败码: " + hCNetSDK.NET_DVR_GetLastError();
+		}
+
+		// 保存回调函数的音频数据
+		FileOutputStream outputStream = new FileOutputStream(file);
+		
+		// 设置回放回调函数
+		PlayDataCallBack playBackCallBack = new PlayDataCallBack(outputStream);
+		hCNetSDK.NET_DVR_SetPlayDataCallBack_V40(iPlayBack, playBackCallBack, Pointer.NULL);
+
+		// 开始计时器
+		Timer playbacktimer = new Timer();// 新建定时器
+		PlaybackTask playbackTask = new PlaybackTask(outputStream, iPlayBack);
+		playbacktimer.schedule(playbackTask, 0, 5000);// 0秒后开始响应函数
+
+		while (!playbackTask.endStatus) {
+			// 等待回放结束
+			try {
+				Thread.sleep(1000);
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+
+		// 如果还没有释放回放资源,需要调用NET_DVR_StopPlayBack释放
+		if (iPlayBack > 0) {
+			hCNetSDK.NET_DVR_StopPlayBack(iPlayBack);
+			iPlayBack = -1;
+		}
+
+		playbacktimer.cancel(); // 关闭定时器
+		return "true";
+	}
+
+	/**
+	 * 获取登录对象
+	 * 
+	 * @param m_sUsername
+	 * @param m_sPassword
+	 * @param m_sDeviceIP
+	 * @param wPort
+	 * @return
+	 * @date 2022年6月23日 下午1:21:08
+	 */
+	private HCNetSDK.NET_DVR_USER_LOGIN_INFO getLoginObject(String m_sUsername, String m_sPassword, String m_sDeviceIP, short wPort) {
+		HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();//设备登录信息
+
+        m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
+        System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length());
+
+        m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
+        System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length());
+
+        m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
+        System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length());
+
+        m_strLoginInfo.wPort = wPort; //SDK端口
+        m_strLoginInfo.bUseAsynLogin = false; //是否异步登录:0- 否,1- 是
+        m_strLoginInfo.write();
+        
+        return m_strLoginInfo;
+	}
+
+    /**
+     * 初始化SDK
+     * 
+     * @return
+     */
+	private boolean init() {
+		if (!isInit) {
+			// 初始化
+			hCNetSDK = HCNetSDK.INSTANCE;
+			isInit = hCNetSDK.NET_DVR_Init();
+		}
+		return isInit;
+	}
+	
+    /**
+     * 获取海康录像机格式的时间
+     * 
+     * @param startParam
+     * @param endParam
+     * @param channle
+     * @return
+     * @date 2022年6月23日 下午1:38:59
+     */
+    private HCNetSDK.NET_DVR_VOD_PARA getPlayBackHkTime(String startParam, String endParam, String streamId) {
+    	Date startTime = DateUtil.parse(startParam);
+    	Date endTime = DateUtil.parse(endParam);
+    	
+        HCNetSDK.NET_DVR_VOD_PARA net_dvr_vod_para = new HCNetSDK.NET_DVR_VOD_PARA();
+		net_dvr_vod_para.dwSize = net_dvr_vod_para.size();
+		//net_dvr_vod_para.struIDInfo.dwChannel = iChannelNo; // 通道号
+		
+		net_dvr_vod_para.struIDInfo.byID = new byte[HCNetSDK.STREAM_ID_LEN];
+        System.arraycopy(streamId.getBytes(), 0, net_dvr_vod_para.struIDInfo.byID, 0, streamId.length());
+		
+		net_dvr_vod_para.struBeginTime.dwYear = DateUtil.year(startTime);
+		net_dvr_vod_para.struBeginTime.dwMonth = DateUtil.month(startTime) + 1;
+		net_dvr_vod_para.struBeginTime.dwDay =  DateUtil.dayOfMonth(startTime);
+		net_dvr_vod_para.struBeginTime.dwHour = DateUtil.hour(startTime, true);
+		net_dvr_vod_para.struBeginTime.dwMinute = DateUtil.minute(startTime);
+		net_dvr_vod_para.struBeginTime.dwSecond = DateUtil.second(startTime);
+		// 停止时间
+		net_dvr_vod_para.struEndTime.dwYear = DateUtil.year(endTime);
+		net_dvr_vod_para.struEndTime.dwMonth = DateUtil.month(endTime) + 1;
+		net_dvr_vod_para.struEndTime.dwDay = DateUtil.dayOfMonth(endTime);
+		net_dvr_vod_para.struEndTime.dwHour = DateUtil.hour(endTime, true);
+		net_dvr_vod_para.struEndTime.dwMinute = DateUtil.minute(endTime);
+		net_dvr_vod_para.struEndTime.dwSecond = DateUtil.second(endTime);
+		net_dvr_vod_para.hWnd = null; // 回放的窗口句柄,若置为空,SDK仍能收到码流数据,但不解码显示
+		net_dvr_vod_para.write();
+		
+        return net_dvr_vod_para;
+    }
+
+}

+ 333 - 0
src/main/java/com/persagy/cameractl/sdk40/PlayBackEventController.java

@@ -0,0 +1,333 @@
+package com.persagy.cameractl.sdk40;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Date;
+import java.util.Timer;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+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.RestController;
+
+import com.persagy.cameractl.sdk40.HCNetSDK.NET_DVR_USER_LOGIN_INFO;
+import com.persagy.cameractl.sdk40.HCNetSDK.NET_DVR_VOD_PARA;
+import com.persagy.cameractl.utils.Camera;
+import com.persagy.cameractl.utils.OtherTools;
+import com.persagy.cameractl.utils.ResultClass;
+import com.sun.jna.Pointer;
+import com.sun.jna.ptr.IntByReference;
+
+import cn.hutool.core.date.DateUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2022年6月23日 上午11:12:34
+ */
+@RestController
+public class PlayBackEventController {
+	public static Logger logger = LoggerFactory.getLogger(PlayBackEventController.class);
+
+	public static String test_stream_id = "18083116593134708100";
+	
+	public static volatile HCNetSDK hCNetSDK;
+	private volatile boolean isInit = false;
+
+	@RequestMapping(value = "/playback/event", method = RequestMethod.POST)
+	public ResultClass play(@RequestBody Camera camera, @PathVariable("operType") String operType) throws Exception {
+		ResultClass returnResult = new ResultClass();
+		returnResult.name = false;
+		
+		// SDK初始化
+		boolean init = this.init();
+		if (!init) {
+			returnResult.reason = "SDK初始化失败";
+			return returnResult;
+		}
+        
+        //登录设备,每一台设备分别登录; 登录句柄是唯一的,可以区分设备
+        HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();//设备信息
+        NET_DVR_USER_LOGIN_INFO m_strLoginInfo = this.getLoginObject(camera.userName, camera.password, camera.cameraIp, (short)camera.cameraPort);
+
+        int lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
+        if (lUserID == -1) {
+        	int errCode = hCNetSDK.NET_DVR_GetLastError();
+        	returnResult.reason = "设备注册失败,失败码:" + errCode;
+			return returnResult;
+        }
+        
+        logger.info(camera.cameraIp + ": login success! " + "device serial number: " + new String(m_strDeviceInfo.struDeviceV30.sSerialNumber).trim());
+        m_strDeviceInfo.read();
+        
+        // nt lChannel = 3;
+        // byStartDChan为IP通道起始通道号, 预览回放NVR的IP通道时需要根据起始通道号进行取值
+        // int lDChannel = (int) m_strDeviceInfo.struDeviceV30.byStartDChan + lChannel -1;
+        int lDChannel = camera.channel;
+        logger.info("channle num: " + lDChannel);
+        
+        //按时间回放和下载
+        String result = null;
+        /*if ("download".equals(operType)) {
+        	result = this.dowmloadRecordByTime(camera.startDateStr, camera.endDateStr, lUserID, lDChannel);
+		} else if ("stream".equals(operType)) {
+			result = this.playBackBytime(camera.startDateStr, camera.endDateStr, lUserID, lDChannel);
+		} else {
+			returnResult.reason = "非法请求";
+			return returnResult;
+		}*/
+        
+        //退出程序时调用,每一台设备分别注销
+        if (hCNetSDK.NET_DVR_Logout(lUserID)) {
+            logger.info("logout success");
+        }
+        
+        // SDK反初始化,释放资源,只需要退出时调用一次
+        // hCNetSDK.NET_DVR_Cleanup();
+		
+        if ("true".equals(result)) {
+        	returnResult.reason = "文件生成成功";
+		} else {
+			returnResult.reason = result;
+		}
+        
+        returnResult.name = true;
+		return returnResult;
+	}
+	
+	/**
+	 * 按时间回放获取码流数据
+	 * 
+	 * @param userID
+	 * @throws IOException 
+	 */
+	public String findFileByEvent(String startParam, String endParam, int userID, int iChannelNo) throws IOException {
+		// 根据事件查找录像文件 -- 入参组装
+		HCNetSDK.NET_DVR_TIME_SEARCH_COND struStartTime = this.getNET_DVR_TIME_SEARCH_COND_Object(startParam);
+		HCNetSDK.NET_DVR_TIME_SEARCH_COND struEndTime = this.getNET_DVR_TIME_SEARCH_COND_Object(endParam);
+		
+		HCNetSDK.NET_DVR_SEARCH_EVENT_PARAM_V50 search_event_param_v50 = new HCNetSDK.NET_DVR_SEARCH_EVENT_PARAM_V50();
+		search_event_param_v50.wMajorType = 100;	// 流ID信息
+		search_event_param_v50.wMinorType = 0;		// 流ID
+		search_event_param_v50.struStartTime = struStartTime;
+		search_event_param_v50.struEndTime = struEndTime;
+		search_event_param_v50.byQuickSearch = 1;
+		
+		HCNetSDK.NET_DVR_STREAM_INFO struIDInfo = new HCNetSDK.NET_DVR_STREAM_INFO();
+		struIDInfo.byID = test_stream_id.getBytes();
+		//struIDInfo.dwSize = struIDInfo.size();
+		
+		search_event_param_v50.uSeniorParam.struStreamIDParam.struIDInfo = struIDInfo;
+		
+		// 根据事件查找录像文件
+		int event_V50 = hCNetSDK.NET_DVR_FindFileByEvent_V50(userID, null);
+		if (event_V50 < 0) {
+			logger.warn("NET_DVR_FindFileByEvent_V50 failure, errorCode: " + hCNetSDK.NET_DVR_GetLastError());
+			return "根据事件查找录像文件失败,错误码:" + hCNetSDK.NET_DVR_GetLastError();
+		}
+		
+		// 逐个获取查找到的文件信息 -- 入参组装
+		HCNetSDK.NET_DVR_TIME_SEARCH searchStruStartTime = this.getNET_DVR_TIME_SEARCH_Object(startParam);
+		HCNetSDK.NET_DVR_TIME_SEARCH searchStruEndTime = this.getNET_DVR_TIME_SEARCH_Object(endParam);
+		
+		HCNetSDK.NET_DVR_SEARCH_EVENT_RET_V50 search_event_ret_v50 = new HCNetSDK.NET_DVR_SEARCH_EVENT_RET_V50();
+		search_event_ret_v50.wMajorType = 100;
+		search_event_ret_v50.wMinorType = 0;
+		search_event_ret_v50.struStartTime = searchStruStartTime;
+		search_event_ret_v50.struEndTime = searchStruEndTime;
+		
+		// 逐个获取查找到的文件信息
+		int nextEvent_V50 = hCNetSDK.NET_DVR_FindNextEvent_V50(event_V50, search_event_ret_v50);
+		if (nextEvent_V50 < 0) {
+			logger.warn("NET_DVR_FindNextEvent_V50 failure, errorCode: " + hCNetSDK.NET_DVR_GetLastError());
+			return "根据事件查找录像文件失败,错误码:" + hCNetSDK.NET_DVR_GetLastError();
+		} else if (nextEvent_V50 == 1002) {
+			try {
+				logger.info("NET_DVR_FindNextEvent_V50 searching ...");
+				Thread.sleep(3000);
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		} else if (nextEvent_V50 == 1004) {
+			logger.info("NET_DVR_FindNextEvent_V50 searching exception");
+			return "查找文件时异常,错误码:" + hCNetSDK.NET_DVR_GetLastError();
+		}
+		
+		// 根据时间进行录像回放
+		NET_DVR_VOD_PARA net_dvr_vod_para = getPlayBackHkTime(startParam, endParam, iChannelNo);
+		int iPlayBack = hCNetSDK.NET_DVR_PlayBackByTime_V40(userID, net_dvr_vod_para);
+		if (iPlayBack <= -1) {
+			logger.warn("playback failure, errorCode: " + hCNetSDK.NET_DVR_GetLastError());
+		}
+		
+		// 开启取流
+		if (!hCNetSDK.NET_DVR_PlayBackControl_V40(iPlayBack, HCNetSDK.NET_DVR_PLAYSTART, null, 0, null, new IntByReference(0))) {
+			logger.warn("NET_DVR_PLAYSTART failure, errorCode: " + hCNetSDK.NET_DVR_GetLastError());
+			return "取流失败,失败码:" + hCNetSDK.NET_DVR_GetLastError();
+		}
+
+		// 保存回调函数的音频数据
+		String targetFile = OtherTools.getVideoFilePath();
+		File file = new File(targetFile);
+		if (!file.exists()) {
+			file.createNewFile();
+		}
+		FileOutputStream outputStream = new FileOutputStream(file);
+		
+		// 设置回放回调函数
+		PlayDataCallBack playBackCallBack = new PlayDataCallBack(outputStream);
+		hCNetSDK.NET_DVR_SetPlayDataCallBack_V40(iPlayBack, playBackCallBack, Pointer.NULL);
+
+		// 开始计时器
+		Timer playbacktimer = new Timer();// 新建定时器
+		PlaybackTask playbackTask = new PlaybackTask(outputStream, iPlayBack);
+		playbacktimer.schedule(playbackTask, 0, 5000);// 0秒后开始响应函数
+
+		while (!playbackTask.endStatus) {
+			// 等待回放结束
+			try {
+				Thread.sleep(1000);
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+
+		// 如果还没有释放回放资源,需要调用NET_DVR_StopPlayBack释放
+		if (iPlayBack > 0) {
+			hCNetSDK.NET_DVR_StopPlayBack(iPlayBack);
+			iPlayBack = -1;
+		}
+
+		playbacktimer.cancel(); // 关闭定时器
+		return "true";
+	}
+
+	/**
+	 * 获取登录对象
+	 * 
+	 * @param m_sUsername
+	 * @param m_sPassword
+	 * @param m_sDeviceIP
+	 * @param wPort
+	 * @return
+	 * @date 2022年6月23日 下午1:21:08
+	 */
+	private HCNetSDK.NET_DVR_USER_LOGIN_INFO getLoginObject(String m_sUsername, String m_sPassword, String m_sDeviceIP, short wPort) {
+		HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();//设备登录信息
+
+        m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
+        System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length());
+
+        m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
+        System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length());
+
+        m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
+        System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length());
+
+        m_strLoginInfo.wPort = wPort; //SDK端口
+        m_strLoginInfo.bUseAsynLogin = false; //是否异步登录:0- 否,1- 是
+        m_strLoginInfo.write();
+        
+        return m_strLoginInfo;
+	}
+
+    /**
+     * 初始化SDK
+     * 
+     * @return
+     */
+	private boolean init() {
+		if (!isInit) {
+			// 初始化
+			hCNetSDK = HCNetSDK.INSTANCE;
+			isInit = hCNetSDK.NET_DVR_Init();
+		}
+		return isInit;
+	}
+	
+    /**
+     * 获取海康录像机格式的时间
+     * 
+     * @param startParam
+     * @param endParam
+     * @param channle
+     * @return
+     * @date 2022年6月23日 下午1:38:59
+     */
+    private HCNetSDK.NET_DVR_VOD_PARA getPlayBackHkTime(String startParam, String endParam, int iChannelNo) {
+    	Date startTime = DateUtil.parse(startParam);
+    	Date endTime = DateUtil.parse(endParam);
+    	
+        HCNetSDK.NET_DVR_VOD_PARA net_dvr_vod_para = new HCNetSDK.NET_DVR_VOD_PARA();
+		net_dvr_vod_para.dwSize = net_dvr_vod_para.size();
+		net_dvr_vod_para.struIDInfo.byID = test_stream_id.getBytes();
+		net_dvr_vod_para.struBeginTime.dwYear = DateUtil.year(startTime);
+		net_dvr_vod_para.struBeginTime.dwMonth = DateUtil.month(startTime) + 1;
+		net_dvr_vod_para.struBeginTime.dwDay =  DateUtil.dayOfMonth(startTime);
+		net_dvr_vod_para.struBeginTime.dwHour = DateUtil.hour(startTime, true);
+		net_dvr_vod_para.struBeginTime.dwMinute = DateUtil.minute(startTime);
+		net_dvr_vod_para.struBeginTime.dwSecond = DateUtil.second(startTime);
+		// 停止时间
+		net_dvr_vod_para.struEndTime.dwYear = DateUtil.year(endTime);
+		net_dvr_vod_para.struEndTime.dwMonth = DateUtil.month(endTime) + 1;
+		net_dvr_vod_para.struEndTime.dwDay = DateUtil.dayOfMonth(endTime);
+		net_dvr_vod_para.struEndTime.dwHour = DateUtil.hour(endTime, true);
+		net_dvr_vod_para.struEndTime.dwMinute = DateUtil.minute(endTime);
+		net_dvr_vod_para.struEndTime.dwSecond = DateUtil.second(endTime);
+		net_dvr_vod_para.hWnd = null; // 回放的窗口句柄,若置为空,SDK仍能收到码流数据,但不解码显示
+		net_dvr_vod_para.write();
+		
+        return net_dvr_vod_para;
+    }
+    
+    /**
+     * 获取海康录像机事件回放的日期对象
+     * 
+     * @param timeParam
+     * @param channle
+     * @return
+     * @date 2022年6月23日 下午1:38:59
+     */
+    private HCNetSDK.NET_DVR_TIME_SEARCH_COND getNET_DVR_TIME_SEARCH_COND_Object(String timeParam) {
+    	Date time = DateUtil.parse(timeParam);
+    	
+        HCNetSDK.NET_DVR_TIME_SEARCH_COND net_dvr_time_search_cond = new HCNetSDK.NET_DVR_TIME_SEARCH_COND();
+        net_dvr_time_search_cond.wYear = (short)DateUtil.year(time);
+        net_dvr_time_search_cond.byMonth = (byte)(DateUtil.month(time) + 1);
+        net_dvr_time_search_cond.byDay =  (byte)DateUtil.dayOfMonth(time);
+        net_dvr_time_search_cond.byHour = (byte)DateUtil.hour(time, true);
+        net_dvr_time_search_cond.byMinute = (byte)DateUtil.minute(time);
+		net_dvr_time_search_cond.bySecond = (byte)DateUtil.second(time);
+		
+        return net_dvr_time_search_cond;
+    }
+    
+    /**
+     * 获取海康录像机事件回放的日期对象
+     * 
+     * @param timeParam
+     * @param channle
+     * @return
+     * @date 2022年6月23日 下午1:38:59
+     */
+    private HCNetSDK.NET_DVR_TIME_SEARCH getNET_DVR_TIME_SEARCH_Object(String timeParam) {
+    	Date time = DateUtil.parse(timeParam);
+    	
+        HCNetSDK.NET_DVR_TIME_SEARCH net_dvr_time_search = new HCNetSDK.NET_DVR_TIME_SEARCH();
+        net_dvr_time_search.wYear = (short)DateUtil.year(time);
+        net_dvr_time_search.byMonth = (byte)(DateUtil.month(time) + 1);
+        net_dvr_time_search.byDay =  (byte)DateUtil.dayOfMonth(time);
+        net_dvr_time_search.byHour = (byte)DateUtil.hour(time, true);
+        net_dvr_time_search.byMinute = (byte)DateUtil.minute(time);
+        net_dvr_time_search.bySecond = (byte)DateUtil.second(time);
+		
+        return net_dvr_time_search;
+    }
+ 
+}

+ 46 - 0
src/main/java/com/persagy/cameractl/sdk40/PlayDataCallBack.java

@@ -0,0 +1,46 @@
+package com.persagy.cameractl.sdk40;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import com.sun.jna.Pointer;
+
+/**
+ * 视频回放回调函数
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2022年6月23日 上午11:31:15
+ */
+public class PlayDataCallBack implements HCNetSDK.FPlayDataCallBack {
+	
+	private FileOutputStream outputStream;
+	
+	public PlayDataCallBack() {
+		
+	}
+	
+	public PlayDataCallBack(FileOutputStream outputStream) {
+		this.outputStream = outputStream;
+	}
+
+	@Override
+	public void invoke(int lPlayHandle, int dwDataType, Pointer pBuffer, int dwBufSize, int dwUser) {
+		//System.out.println("回放码流回调, 数据类型: " + dwDataType + ", 数据长度:" + dwBufSize);
+        
+        //将设备发送过来的回放码流数据写入文件
+        long offset = 0;
+        ByteBuffer buffers = pBuffer.getByteBuffer(offset, dwBufSize);
+        byte[] bytes = new byte[dwBufSize];
+        buffers.rewind();
+        buffers.get(bytes);
+        try {
+            outputStream.write(bytes);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+	}
+
+}

+ 83 - 0
src/main/java/com/persagy/cameractl/sdk40/PlaybackTask.java

@@ -0,0 +1,83 @@
+package com.persagy.cameractl.sdk40;
+
+import static com.persagy.cameractl.sdk40.PlayBackController.hCNetSDK;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.sun.jna.ptr.IntByReference;
+
+/**
+ * 视频回放的定时器任务
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2022年6月23日 上午11:35:01
+ */
+public class PlaybackTask extends java.util.TimerTask {
+	public static Logger logger = LoggerFactory.getLogger(PlaybackTask.class);
+	
+	public volatile boolean endStatus = false;
+	
+	public volatile int iPlayBack;
+	
+	private FileOutputStream outputStream;
+	
+	public PlaybackTask (FileOutputStream outputStream, int iPlayBack) {
+		this.iPlayBack = iPlayBack;
+		this.outputStream = outputStream;
+	}
+	
+	@Override
+	public void run() {
+		logger.info("========= playbackTask start =========");
+
+		IntByReference nPos = new IntByReference(0);
+		boolean bret = hCNetSDK.NET_DVR_PlayBackControl_V40(iPlayBack, HCNetSDK.NET_DVR_PLAYGETPOS, null, 0, nPos.getPointer(), new IntByReference(0));
+		if (bret) {
+			logger.info("playback download progress: " + nPos.getValue());
+		} else {
+			logger.info("get playback progress faliure, errorCode: " + hCNetSDK.NET_DVR_GetLastError());
+			endStatus = true;
+		}
+
+		// 网络异常导致回放连接断开
+		if (nPos.getValue() > 100) {
+			// 停止回放,释放资源
+			hCNetSDK.NET_DVR_StopPlayBack(iPlayBack);
+			iPlayBack = -1;
+			if (outputStream != null) {
+				try {
+					outputStream.close();
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+			endStatus = true;
+			logger.info("playback exception exit, errorCode: " + hCNetSDK.NET_DVR_GetLastError());
+		}
+
+		// 回放结束
+		if (nPos.getValue() == 100) {
+			// 停止回放,释放资源
+			hCNetSDK.NET_DVR_StopPlayBack(iPlayBack);
+			iPlayBack = -1;
+			if (outputStream != null) {
+				try {
+					outputStream.close();
+				} catch (IOException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+			endStatus = true;
+			logger.info("playback end exit");
+		}
+
+	}
+
+}

+ 205 - 0
src/main/java/com/persagy/cameractl/temp/ClinetDemo.java

@@ -0,0 +1,205 @@
+package com.persagy.cameractl.temp;
+
+import com.persagy.cameractl.sdk40.HCNetSDK;
+import com.sun.jna.Native;
+import com.sun.jna.Pointer;
+import java.util.Timer;
+
+/**
+ * @create 2020-12-24-17:55
+ */
+public class ClinetDemo {
+
+    int iErr = 0;
+    static HCNetSDK hCNetSDK = null;
+    static PlayCtrl playControl = null;
+    static int lUserID = 0;//用户句柄
+    static int lAlarmHandle = -1;//报警布防句柄
+    static int lListenHandle = -1;//报警监听句柄
+
+    static boolean bSaveHandle = false;
+    Timer Playbacktimer;//回放用定时器
+
+    static FExceptionCallBack_Imp fExceptionCallBack;
+    static int FlowHandle;
+
+    static class FExceptionCallBack_Imp implements HCNetSDK.FExceptionCallBack {
+        public void invoke(int dwType, int lUserID, int lHandle, Pointer pUser) {
+            System.out.println("异常事件类型:"+dwType);
+            return;
+        }
+    }
+
+    public static void main(String[] args) throws InterruptedException {
+
+        if (hCNetSDK == null&&playControl==null) {
+            if (!CreateSDKInstance()) {
+                System.out.println("Load SDK fail");
+                return;
+            }
+            if (!CreatePlayInstance()) {
+                System.out.println("Load PlayCtrl fail");
+                return;
+            }
+        }
+        //linux系统建议调用以下接口加载组件库
+        if (osSelect.isLinux()) {
+            HCNetSDK.BYTE_ARRAY ptrByteArray1 = new HCNetSDK.BYTE_ARRAY(256);
+            HCNetSDK.BYTE_ARRAY ptrByteArray2 = new HCNetSDK.BYTE_ARRAY(256);
+            //这里是库的绝对路径,请根据实际情况修改,注意改路径必须有访问权限
+            String strPath1 = System.getProperty("user.dir") + "/lib/libcrypto.so.1.1";
+            String strPath2 = System.getProperty("user.dir") + "/lib/libssl.so.1.1";
+
+            System.arraycopy(strPath1.getBytes(), 0, ptrByteArray1.byValue, 0, strPath1.length());
+            ptrByteArray1.write();
+            hCNetSDK.NET_DVR_SetSDKInitCfg(3, ptrByteArray1.getPointer());
+
+            System.arraycopy(strPath2.getBytes(), 0, ptrByteArray2.byValue, 0, strPath2.length());
+            ptrByteArray2.write();
+            hCNetSDK.NET_DVR_SetSDKInitCfg(4, ptrByteArray2.getPointer());
+
+            String strPathCom = System.getProperty("user.dir") + "/lib";
+            HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH();
+            System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length());
+            struComPath.write();
+            hCNetSDK.NET_DVR_SetSDKInitCfg(2, struComPath.getPointer());
+        }
+
+        //SDK初始化,一个程序只需要调用一次
+        boolean initSuc = hCNetSDK.NET_DVR_Init();
+        
+        if (initSuc != true) {
+            System.out.println("初始化失败");
+        }
+        
+        //异常消息回调
+        if(fExceptionCallBack == null)
+        {
+            fExceptionCallBack = new FExceptionCallBack_Imp();
+        }
+        
+        Pointer pUser = null;
+        if (!hCNetSDK.NET_DVR_SetExceptionCallBack_V30(0, 0, fExceptionCallBack, pUser)) {
+            return ;
+        }
+        System.out.println("设置异常消息回调成功");
+
+        //启动SDK写日志
+        hCNetSDK.NET_DVR_SetLogToFile(3, "..\\sdkLog\\", false);
+
+        //登录设备,每一台设备分别登录; 登录句柄是唯一的,可以区分设备
+        HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();//设备登录信息
+        HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();//设备信息
+
+        String m_sDeviceIP = "10.17.34.102";//设备ip地址
+        m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
+        System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length());
+
+        String m_sUsername = "admin";//设备用户名
+        m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
+        System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length());
+
+        String m_sPassword = "hik12345";//设备密码
+        m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
+        System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length());
+
+        m_strLoginInfo.wPort = 8000; //SDK端口
+        m_strLoginInfo.bUseAsynLogin = false; //是否异步登录:0- 否,1- 是
+        m_strLoginInfo.write();
+
+        lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
+        if (lUserID == -1) {
+            System.out.println("登录失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
+        } else {
+            System.out.println(m_sDeviceIP + ":设备登录成功! " + "设备序列号:" + new String(m_strDeviceInfo.struDeviceV30.sSerialNumber).trim());
+            m_strDeviceInfo.read();
+        }
+        
+        int lChannel = 3;
+        //byStartDChan为IP通道起始通道号, 预览回放NVR的IP通道时需要根据起始通道号进行取值
+        int lDChannel = (int)m_strDeviceInfo.struDeviceV30.byStartDChan + lChannel -1;
+        System.out.println("预览通道号: " + lDChannel);
+        
+        //注释掉的代码也可以参考,去掉注释可以运行
+        //VideoDemo.getIPChannelInfo(lUserID); //获取IP通道             
+        
+        VideoDemo.RealPlay(lUserID, lDChannel);   //预览
+
+        //按时间回放和下载
+        new VideoDemo().PlayBackBytime(lUserID, lDChannel);
+        new VideoDemo().DowmloadRecordByTime(lUserID, lDChannel); //按时间下载录像
+        
+        //按时间回放和下载录像,需要等待回放和下载完成后调用注销和释放接口
+
+        //按录像文件回放和下载
+        VideoDemo.DownloadRecordByFile(lUserID, lDChannel);//录像文件查找下载
+        VideoDemo.playBackByfile(lUserID, lDChannel);
+        Thread.sleep(3000);
+        
+        //退出程序时调用,每一台设备分别注销
+        if (hCNetSDK.NET_DVR_Logout(lUserID)) {
+            System.out.println("注销成功");
+        }
+        
+        //SDK反初始化,释放资源,只需要退出时调用一次
+        hCNetSDK.NET_DVR_Cleanup();
+        return;
+    }
+
+    /**
+     * 动态库加载
+     *
+     * @return
+     */
+    private static boolean CreateSDKInstance() {
+        if (hCNetSDK == null) {
+            synchronized (HCNetSDK.class) {
+                String strDllPath = "";
+                try {
+                    if (osSelect.isWindows())
+                        //win系统加载库路径
+                        strDllPath = System.getProperty("user.dir") + "\\lib\\HCNetSDK.dll";
+
+                    else if (osSelect.isLinux())
+                        //Linux系统加载库路径
+                        strDllPath = System.getProperty("user.dir") + "/lib/libhcnetsdk.so";
+                    hCNetSDK = (HCNetSDK) Native.loadLibrary(strDllPath, HCNetSDK.class);
+                } catch (Exception ex) {
+                    System.out.println("loadLibrary: " + strDllPath + " Error: " + ex.getMessage());
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 播放库加载
+     *
+     * @return
+     */
+    private static boolean CreatePlayInstance() {
+        if (playControl == null) {
+            synchronized (PlayCtrl.class) {
+                String strPlayPath = "";
+                try {
+                    if (osSelect.isWindows())
+                        //win系统加载库路径
+                    strPlayPath = System.getProperty("user.dir") + "\\lib\\PlayCtrl.dll";
+                    else if (osSelect.isLinux())
+                        //Linux系统加载库路径
+                    strPlayPath = System.getProperty("user.dir") + "/lib/libPlayCtrl.so";
+                    playControl=(PlayCtrl) Native.loadLibrary(strPlayPath,PlayCtrl.class);
+
+                } catch (Exception ex) {
+                    System.out.println("loadLibrary: " + strPlayPath + " Error: " + ex.getMessage());
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+}
+
+
+

+ 19 - 0
src/main/java/com/persagy/cameractl/temp/CommonUtil.java

@@ -0,0 +1,19 @@
+package com.persagy.cameractl.temp;
+
+public class CommonUtil {
+
+	// SDK时间解析
+	public static String parseTime(int time) {
+		int dwYear = (time >> 26) + 2000;
+		int dwMonth = (time >> 22) & 15;
+		int dwDay = (time >> 17) & 31;
+		int dwHour = (time >> 12) & 31;
+		int dwMinute = (time >> 6) & 63;
+		int dwSecond = (time >> 0) & 63;
+
+		String sTime = String.format("%04d", dwYear) + String.format("%02d", dwMonth) + String.format("%02d", dwDay)
+				+ String.format("%02d", dwHour) + String.format("%02d", dwMinute) + String.format("%02d", dwSecond);
+		return sTime;
+	}
+
+}

Plik diff jest za duży
+ 10503 - 0
src/main/java/com/persagy/cameractl/temp/HCNetSDK.java


+ 853 - 0
src/main/java/com/persagy/cameractl/temp/VideoDemo.java

@@ -0,0 +1,853 @@
+package com.persagy.cameractl.temp;
+
+import com.persagy.cameractl.sdk40.HCNetSDK;
+import com.sun.jna.Pointer;
+import com.sun.jna.ptr.ByteByReference;
+import com.sun.jna.ptr.IntByReference;
+
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Timer;
+
+import static com.persagy.cameractl.temp.ClinetDemo.hCNetSDK;
+import static com.persagy.cameractl.temp.ClinetDemo.playControl;
+
+/**
+ * 视频取流预览,下载,抓图
+ * @create 2022-03-30-9:48
+ */
+@SuppressWarnings("unused")
+public class VideoDemo {
+    Timer Downloadtimer;//下载用定时器
+    Timer Playbacktimer;//回放用定时器
+    static FRealDataCallBack fRealDataCallBack;//预览回调函数实现
+    static fPlayEScallback fPlayescallback; //裸码流回调函数
+    static playDataCallBack playBackCallBack; //回放码流回调
+    static int lPlay = -1;  //预览句柄
+    int m_lLoadHandle;
+    int iPlayBack; //回放句柄
+    static File file;
+    static FileOutputStream outputStream;
+    static IntByReference m_lPort= new IntByReference(-1);
+    static String resultFileName = "..\\Download" + new String("returnFile" + ".h264");
+    static FileOutputStream fileOutputStream = null;
+    static int fileLenth = 0;
+    static boolean bEnd = false;
+    
+    public static void RealPlay(int userID, int iChannelNo) {
+        if (userID == -1) {
+            System.out.println("请先注册");
+            return;
+        }
+        HCNetSDK.NET_DVR_PREVIEWINFO strClientInfo = new HCNetSDK.NET_DVR_PREVIEWINFO();
+        strClientInfo.read();
+        strClientInfo.hPlayWnd = null;  //窗口句柄,从回调取流不显示一般设置为空
+        strClientInfo.lChannel = iChannelNo;  //通道号
+        strClientInfo.dwStreamType=0; //0-主码流,1-子码流,2-三码流,3-虚拟码流,以此类推
+        strClientInfo.dwLinkMode=0; //连接方式:0- TCP方式,1- UDP方式,2- 多播方式,3- RTP方式,4- RTP/RTSP,5- RTP/HTTP,6- HRUDP(可靠传输) ,7- RTSP/HTTPS,8- NPQ
+        strClientInfo.bBlocked=1;
+        strClientInfo.write();
+        
+        //回调函数定义必须是全局的
+        if (fRealDataCallBack == null) {
+            fRealDataCallBack = new FRealDataCallBack();
+        }
+        
+        //开启预览
+        lPlay = hCNetSDK.NET_DVR_RealPlay_V40(userID, strClientInfo, fRealDataCallBack , null);
+        if (lPlay == -1) {
+            int iErr = hCNetSDK.NET_DVR_GetLastError();
+            System.out.println("取流失败" + iErr);
+            return;
+        }
+        System.out.println("取流成功");
+
+        //设置裸码流回调函数
+/*        if (fPlayescallback==null)
+        {
+            fPlayescallback=new fPlayEScallback();
+        }
+        boolean setcallback=ClientDemo.hCNetSDK.NET_DVR_SetESRealPlayCallBack(lPlay,fPlayescallback,null);
+        if (setcallback==false)
+        {
+            System.out.println("设置裸码流回调失败,错误码:"+ClientDemo.hCNetSDK.NET_DVR_GetLastError());
+        }*/
+        
+        try {
+            Thread.sleep(3000);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+        
+        //取流解码过程中播放库从解码码流中抓图
+        getPicbyPlayCtrl();
+        
+        /**
+         * 预览一段时间;如果要一直取流预览,需要保证程序一直运行
+         */
+        try {
+			Thread.sleep(5000);
+		} catch (InterruptedException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+        if (VideoDemo.lPlay>=0) {
+            if (hCNetSDK.NET_DVR_StopRealPlay(VideoDemo.lPlay))
+            {
+                System.out.println("停止预览成功");
+            }
+        }
+    }
+
+    //播放库抓图
+    public static void getPicbyPlayCtrl(){
+
+        IntByReference pWidth = new IntByReference(0);
+        IntByReference pHieght = new IntByReference(0);
+        boolean bFlag = playControl.PlayM4_GetPictureSize(m_lPort.getValue(), pWidth, pHieght);
+        if (!bFlag) {
+            System.out.println("获取失败:" + playControl.PlayM4_GetLastError(m_lPort.getValue()));
+        }
+        System.out.println(pWidth.getValue());
+        System.out.println(pHieght.getValue());
+        IntByReference RealPicSize = new IntByReference(0);
+        int picsize = pWidth.getValue() * pHieght.getValue() * 5;
+        HCNetSDK.BYTE_ARRAY picByte = new HCNetSDK.BYTE_ARRAY(picsize);
+        picByte.write();
+        Pointer pByte = picByte.getPointer();
+        boolean b_GetPic = playControl.PlayM4_GetJPEG(m_lPort.getValue(), pByte, picsize, RealPicSize);
+        if (!b_GetPic) {
+            System.out.println("抓图失败:" + playControl.PlayM4_GetLastError(m_lPort.getValue()));
+        }
+        picByte.read();
+        SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
+        String newName = sf.format(new Date());
+        FileOutputStream fout = null;
+        try {
+
+            fout = new FileOutputStream(System.getProperty("user.dir") + "//pic//" + newName + ".jpg");
+            //将字节写入文件
+            long offset = 0;
+            ByteBuffer buffers = pByte.getByteBuffer(offset, RealPicSize.getValue());
+            byte[] bytes = new byte[RealPicSize.getValue()];
+            buffers.rewind();
+            buffers.get(bytes);
+            fout.write(bytes);
+            fout.close();
+        } catch (FileNotFoundException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        System.out.println("抓图成功!");
+
+    }
+
+
+    /**
+     * 按时间回放获取码流数据
+     * @param userID
+     */
+
+    public void PlayBackBytime(int userID, int iChannelNo)
+    {
+        file = new File(System.getProperty("user.dir") + "\\Download\\Videodatabytime.mp4");  //保存回调函数的音频数据
+
+        if (!file.exists()) {
+            try {
+                file.createNewFile();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        try {
+            outputStream = new FileOutputStream(file);
+        } catch (FileNotFoundException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        HCNetSDK.NET_DVR_VOD_PARA net_dvr_vod_para = new HCNetSDK.NET_DVR_VOD_PARA();
+        net_dvr_vod_para.dwSize=net_dvr_vod_para.size();
+        net_dvr_vod_para.struIDInfo.dwChannel = iChannelNo; //通道号
+        net_dvr_vod_para.struBeginTime.dwYear=2022;
+        net_dvr_vod_para.struBeginTime.dwMonth=4;
+        net_dvr_vod_para.struBeginTime.dwDay=17;
+        net_dvr_vod_para.struBeginTime.dwHour=10;
+        net_dvr_vod_para.struBeginTime.dwMinute=05;
+        net_dvr_vod_para.struBeginTime.dwSecond=00;
+        //停止时间
+        net_dvr_vod_para.struEndTime.dwYear=2022;
+        net_dvr_vod_para.struEndTime.dwMonth=4;
+        net_dvr_vod_para.struEndTime.dwDay=17;
+        net_dvr_vod_para.struEndTime.dwHour=10;
+        net_dvr_vod_para.struEndTime.dwMinute=8;
+        net_dvr_vod_para.struEndTime.dwSecond=00;
+        net_dvr_vod_para.hWnd = null; // 回放的窗口句柄,若置为空,SDK仍能收到码流数据,但不解码显示
+        net_dvr_vod_para.write();
+
+        int iPlayBack = hCNetSDK.NET_DVR_PlayBackByTime_V40(userID,net_dvr_vod_para);
+        if (iPlayBack<=-1)
+        {
+            System.out.println("按时间回放失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
+            return;
+        }
+
+        //开启取流        
+        if(!hCNetSDK.NET_DVR_PlayBackControl_V40(iPlayBack, HCNetSDK.NET_DVR_PLAYSTART, null, 0, null, new IntByReference(0)))
+    	{
+    		System.out.println("NET_DVR_PLAYSTART失败,错误号:" + hCNetSDK.NET_DVR_GetLastError());
+    		return;
+    	}
+        
+        //设置回放回调函数
+        if (playBackCallBack==null)
+        {
+            playBackCallBack = new playDataCallBack();
+        }
+        boolean bRet =hCNetSDK.NET_DVR_SetPlayDataCallBack_V40(iPlayBack, playBackCallBack, Pointer.NULL);
+      
+        //开始计时器
+        Playbacktimer = new Timer();//新建定时器
+        Playbacktimer.schedule(new PlaybackTask(), 0, 5000);//0秒后开始响应函数
+        
+        while(!bEnd)
+        {
+            //等待回放结束
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+        
+        //如果还没有释放回放资源,需要调用NET_DVR_StopPlayBack释放
+        if(iPlayBack > 0)
+        {
+        	hCNetSDK.NET_DVR_StopPlayBack(iPlayBack);
+            iPlayBack = -1;
+        }
+        
+        Playbacktimer.cancel();  //关闭定时器      
+        return;
+    }
+
+
+    public static void playBackByfile(int userID, int iChannelNo)
+    {
+        file = new File(System.getProperty("user.dir") + "\\Download\\Videodatabyfile.mp4");  //保存回调函数的音频数据
+
+        if (!file.exists()) {
+            try {
+                file.createNewFile();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        try {
+            outputStream = new FileOutputStream(file);
+        } catch (FileNotFoundException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        
+        String strFileName="";
+        HCNetSDK.NET_DVR_FILECOND_V40 struFileCond = new HCNetSDK.NET_DVR_FILECOND_V40();
+        struFileCond.read();
+        struFileCond.lChannel= iChannelNo; //通道号 NVR设备路数小于32路的起始通道号从33开始,依次增加
+        struFileCond.byFindType=0;  //录象文件类型 0=定时录像
+        //起始时间
+        struFileCond.struStartTime.dwYear=2022;
+        struFileCond.struStartTime.dwMonth=4;
+        struFileCond.struStartTime.dwDay=17;
+        struFileCond.struStartTime.dwHour=10;
+        struFileCond.struStartTime.dwMinute=00;
+        struFileCond.struStartTime.dwSecond=00;
+        //停止时间
+        struFileCond.struStopTime.dwYear=2022;
+        struFileCond.struStopTime.dwMonth=4;
+        struFileCond.struStopTime.dwDay=17;
+        struFileCond.struStopTime.dwHour=10;
+        struFileCond.struStopTime.dwMinute=10;
+        struFileCond.struStopTime.dwSecond=0;
+        struFileCond.write();
+        int  FindFileHandle=hCNetSDK.NET_DVR_FindFile_V40(userID,struFileCond);
+        if (FindFileHandle<=-1)
+        {
+            System.out.println("查找建立失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
+        }
+
+        while (true)
+        {
+            HCNetSDK.NET_DVR_FINDDATA_V40 struFindData = new HCNetSDK.NET_DVR_FINDDATA_V40();
+
+            long State=hCNetSDK.NET_DVR_FindNextFile_V40(FindFileHandle,struFindData);
+            if (State<=-1)
+            {
+
+                System.out.println("查找失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
+                return;
+
+            }
+
+            else if (State==1000)  //获取文件信息成功
+            {
+                struFindData.read();
+                try {
+                    strFileName=new String(struFindData.sFileName,"UTF-8").trim();
+                    System.out.println("文件名称:"+strFileName);
+                    System.out.println("文件大小:"+struFindData.dwFileSize);
+                } catch (UnsupportedEncodingException e) {
+                    e.printStackTrace();
+                }
+                System.out.println("获取文件成功");
+                break;
+
+            }
+            else if (State==1001) //未查找到文件
+            {
+                System.out.println("未查找到文件");
+                break;
+
+            }
+            else if (State==1002) //正在查找请等待
+            {
+                System.out.println("正在查找,请等待");
+                continue;
+
+            }
+
+            else if (State==1003) //没有更多的文件,查找结束
+            {
+                System.out.println("没有更多的文件,查找结束");
+                break;
+
+            }
+            else if (State==1004) //查找文件时异常
+            {
+
+                System.out.println("没有更多的文件,查找结束");
+                break;
+
+            }
+            else if (State==1005) //查找文件超时
+            {
+
+                System.out.println("没有更多的文件,查找结束");
+                break;
+
+            }
+
+        }
+        boolean b_CloseHandle=hCNetSDK.NET_DVR_FindClose_V30(FindFileHandle);
+        if (!b_CloseHandle) {
+            System.out.println("关闭失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
+            return;
+        }
+
+        int lPlayByFileHandle=hCNetSDK.NET_DVR_PlayBackByName(userID,strFileName,null);
+        if (lPlayByFileHandle<=-1)
+        {
+            System.out.println("按文件回放失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
+            return;
+        }
+        IntByReference intP1=new IntByReference(0);
+        IntByReference intInlen=new IntByReference(0);
+        boolean b_PlayBackStart=hCNetSDK.NET_DVR_PlayBackControl_V40(lPlayByFileHandle,HCNetSDK.NET_DVR_PLAYSTART,intP1.getPointer(),4,Pointer.NULL,intInlen);
+        if (!b_PlayBackStart) {
+            System.out.println("开始播放失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
+            return;
+        }
+        if (playBackCallBack==null)
+        {
+            playBackCallBack=new playDataCallBack();
+        }
+        
+		boolean bRet = hCNetSDK.NET_DVR_SetPlayDataCallBack_V40(lPlayByFileHandle,playBackCallBack,Pointer.NULL);
+        while (true)
+        {
+            int Pos=hCNetSDK.NET_DVR_GetDownloadPos(lPlayByFileHandle);
+            if (Pos!=100)
+            {
+                System.out.println("回放进度:"+Pos);
+
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+                continue;
+            }
+            else {
+                break;
+            }
+        }
+        boolean b_Stop=hCNetSDK.NET_DVR_StopPlayBack(lPlayByFileHandle);
+        if (!b_Stop) {
+            System.out.println("停止回放失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
+            return;
+        }
+        System.out.println("回放成功");
+        return;
+    }
+
+    //按文件下载录像(设置转成3GP格式)
+    public static void DownloadRecordByFile(int userID, int iChannelNo)
+    {
+    	bEnd = false;
+    	
+        String strFileName="";
+        HCNetSDK.NET_DVR_FILECOND_V40 struFileCond = new HCNetSDK.NET_DVR_FILECOND_V40();
+        struFileCond.read();
+        struFileCond.lChannel= iChannelNo; //通道号 NVR设备路数小于32路的起始通道号从33开始,依次增加
+        struFileCond.byFindType=0;  //录象文件类型 0=定时录像
+        //起始时间
+        struFileCond.struStartTime.dwYear=2022;
+        struFileCond.struStartTime.dwMonth=4;
+        struFileCond.struStartTime.dwDay=9;
+        struFileCond.struStartTime.dwHour=0;
+        struFileCond.struStartTime.dwMinute=00;
+        struFileCond.struStartTime.dwSecond=00;
+        //停止时间
+        struFileCond.struStopTime.dwYear=2022;
+        struFileCond.struStopTime.dwMonth=4;
+        struFileCond.struStopTime.dwDay=9;
+        struFileCond.struStopTime.dwHour=24;
+        struFileCond.struStopTime.dwMinute=0;
+        struFileCond.struStopTime.dwSecond=0;
+        struFileCond.write();
+        
+        int  FindFileHandle=hCNetSDK.NET_DVR_FindFile_V40(userID,struFileCond);
+        if (FindFileHandle<=-1)
+        {
+            System.out.println("查找建立失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
+        }
+
+        boolean bFind = false;
+        while (true)
+        {
+            HCNetSDK.NET_DVR_FINDDATA_V40 struFindData = new HCNetSDK.NET_DVR_FINDDATA_V40();
+
+            long State=hCNetSDK.NET_DVR_FindNextFile_V40(FindFileHandle,struFindData);
+            if (State<=-1)
+            {
+                System.out.println("查找失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
+                return;
+            }
+
+            else if (State==1000)  //获取文件信息成功
+            {
+                struFindData.read();
+                try {
+                    strFileName=new String(struFindData.sFileName,"UTF-8").trim();
+                    System.out.println("文件名称:"+strFileName);
+                    System.out.println("文件大小:"+struFindData.dwFileSize);
+                } catch (UnsupportedEncodingException e) {
+                    e.printStackTrace();
+                }
+                System.out.println("获取文件成功");
+                bFind = true;
+                break;
+            }
+            else if (State==1001) //未查找到文件
+            {
+                System.out.println("未查找到文件");
+                break;
+            }
+            else if (State==1002) //正在查找请等待
+            {
+                System.out.println("正在查找,请等待");
+                continue;
+            }
+
+            else if (State==1003) //没有更多的文件,查找结束
+            {
+                System.out.println("没有更多的文件,查找结束");
+                break;
+            }
+            else if (State==1004) //查找文件时异常
+            {
+                System.out.println("没有更多的文件,查找结束");
+                break;
+            }
+            else if (State==1005) //查找文件超时
+            {
+
+                System.out.println("没有更多的文件,查找结束");
+                break;
+            }
+
+        }
+        boolean b_CloseHandle=hCNetSDK.NET_DVR_FindClose_V30(FindFileHandle);
+        if (!b_CloseHandle) {
+            System.out.println("关闭失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
+            return;
+        }
+        
+        if(!bFind)
+        {
+        	return; //没有查找到文件
+        }
+
+        //按文件下载录像
+        String SaveDir=".\\Download\\test.mp4";
+
+        int FileName=hCNetSDK.NET_DVR_GetFileByName(userID, strFileName, SaveDir.getBytes());
+        if (FileName<=-1)
+        {
+            System.out.println("下载录像失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
+            return;
+        }
+        //转码3GP命令
+//        IntByReference intP=new IntByReference(5);
+/*        boolean b_PlayBack=hCNetSDK.NET_DVR_PlayBackControl_V40(FileName,32,intP.getPointer(),4,Pointer.NULL,0);
+        if (!b_PlayBack) {
+            System.out.println("转封装失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
+            return;
+        }*/
+
+        IntByReference intP1=new IntByReference(0);
+        IntByReference intInlen=new IntByReference(0);
+        boolean b_PlayBackStart=hCNetSDK.NET_DVR_PlayBackControl_V40(FileName,HCNetSDK.NET_DVR_PLAYSTART,intP1.getPointer(),4,Pointer.NULL,intInlen);
+        if (!b_PlayBackStart) {
+            System.out.println("开始播放失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
+            return;
+        }
+
+/*        IntByReference intP=new IntByReference(30*1024);
+        IntByReference intInlen1=new IntByReference(0);
+        boolean b_PlayBack=hCNetSDK.NET_DVR_PlayBackControl_V40(FileName,24,intP.getPointer(),4, Pointer.NULL,intInlen1);
+        if (!b_PlayBack) {
+            System.out.println("设置下载速度失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
+            return;
+        }*/
+        while (true)
+        {
+            int Pos=hCNetSDK.NET_DVR_GetDownloadPos(FileName);
+            if (Pos!=100)
+            {
+                System.out.println("下载进度:"+Pos);
+                
+                try {
+					Thread.sleep(1000);
+				} catch (InterruptedException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				} 
+                continue;
+            }
+            else {
+                break;
+            }
+        }
+        boolean b_Stop=hCNetSDK.NET_DVR_StopGetFile(FileName);
+        if (!b_Stop) {
+            System.out.println("停止下载失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
+            return;
+        }
+        System.out.println("下载成功");
+        return;
+    }
+
+    //按时间下载录像(不支持转码3GP格式)
+    public  void DowmloadRecordByTime(int userID, int iChannelNo)
+    {
+    	bEnd = false;
+    	
+        HCNetSDK.NET_DVR_PLAYCOND net_dvr_playcond = new HCNetSDK.NET_DVR_PLAYCOND();
+        net_dvr_playcond.read();
+        net_dvr_playcond.dwChannel = iChannelNo; //通道号 NVR设备路数小于32路的起始通道号从33开始,依次增加
+       
+        //开始时间
+        net_dvr_playcond.struStartTime.dwYear=2022;
+        net_dvr_playcond.struStartTime.dwMonth=4;
+        net_dvr_playcond.struStartTime.dwDay=17;
+        net_dvr_playcond.struStartTime.dwHour=10;
+        net_dvr_playcond.struStartTime.dwMinute=00;
+        net_dvr_playcond.struStartTime.dwSecond=00;
+        //停止时间
+        net_dvr_playcond.struStopTime.dwYear=2022;
+        net_dvr_playcond.struStopTime.dwMonth=4;
+        net_dvr_playcond.struStopTime.dwDay=17;
+        net_dvr_playcond.struStopTime.dwHour=10;
+        net_dvr_playcond.struStopTime.dwMinute=10;
+        net_dvr_playcond.struStopTime.dwSecond=00;
+        net_dvr_playcond.write();
+        
+        String sFileName = ".\\Download\\" + System.currentTimeMillis() + ".mp4";
+        System.out.println(sFileName);
+       
+        m_lLoadHandle = hCNetSDK.NET_DVR_GetFileByTime_V40(userID, sFileName, net_dvr_playcond);
+        if (m_lLoadHandle >= 0)
+        {
+        	if(!hCNetSDK.NET_DVR_PlayBackControl_V40(m_lLoadHandle, HCNetSDK.NET_DVR_PLAYSTART, null, 0, null, new IntByReference(0)))
+        	{
+        		int iErr = hCNetSDK.NET_DVR_GetLastError();
+        		System.out.println("NET_DVR_PLAYSTART失败,错误号:" + iErr);
+        		return;
+        	}            
+        
+/*            IntByReference intP=new IntByReference(5*8*1024);
+            IntByReference intInlen=new IntByReference(0);
+            boolean b_PlayBack=ClientDemo.hCNetSDK.NET_DVR_PlayBackControl_V40(m_lLoadHandle,24,intP.getPointer(),4,Pointer.NULL,intInlen);
+            if (!b_PlayBack) {
+                System.out.println("设置下载速度失败,错误码为" + ClientDemo.hCNetSDK.NET_DVR_GetLastError());
+                return;
+            }*/
+            Date nowTime = new Date(System.currentTimeMillis());
+            SimpleDateFormat sdFormatter = new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss");
+            System.out.println("开始下载时间:"+sdFormatter.format(nowTime));
+            Downloadtimer = new Timer();//新建定时器
+            Downloadtimer.schedule(new DownloadTask(), 0, 5000);//0秒后开始响应函数
+            
+            while(!bEnd)
+            {
+                //等待下载结束
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+            }
+            
+            //如果还没有释放下载资源,需要调用NET_DVR_StopGetFile释放
+            if(m_lLoadHandle > 0)
+            {
+            	hCNetSDK.NET_DVR_StopGetFile(m_lLoadHandle);
+            	m_lLoadHandle = -1;
+            }
+            
+            Downloadtimer.cancel(); //关闭定时器
+        } else
+        {
+            System.out.println("按时间下载失败");
+            System.out.println("laste error " + hCNetSDK.NET_DVR_GetLastError());
+            return;
+        }
+    }
+
+    /*************************************************
+     类:      DownloadTask
+     类描述:  下载定时器响应函数
+     *************************************************/
+     class DownloadTask extends java.util.TimerTask
+    {
+        //定时器函数
+        @Override
+        public void run()
+        {
+        	System.out.println("定时器触发,下载句柄iPlayBack:" + m_lLoadHandle);
+        	
+            IntByReference nPos = new IntByReference(0);            
+            if(!hCNetSDK.NET_DVR_PlayBackControl_V40(m_lLoadHandle, HCNetSDK.NET_DVR_PLAYGETPOS, null, 0, nPos.getPointer(), new IntByReference(0)))
+            {
+            	bEnd = true;
+        		System.out.println("NET_DVR_PLAYGETPOS失败,错误号:" + hCNetSDK.NET_DVR_GetLastError());
+            }
+            
+            if (nPos.getValue() > 100)
+            {
+                m_lLoadHandle=-1;
+                Downloadtimer.cancel();
+                bEnd = true;
+                System.out.println( "由于网络原因或DVR忙,下载异常终止!");
+            }
+            
+            if (nPos.getValue() == 100)
+            {
+                Date nowTime = new Date(System.currentTimeMillis());
+                SimpleDateFormat sdFormatter = new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss");
+                System.out.println("结束下载时间:"+sdFormatter.format(nowTime));
+                m_lLoadHandle=-1;
+                Downloadtimer.cancel();
+                bEnd = true;
+                System.out.println("按时间下载结束!");
+            }
+        }
+    }
+
+
+    class PlaybackTask extends java.util.TimerTask
+    {
+        //定时器函数
+        @Override
+        public void run()
+        {            
+            System.out.println("定时器触发,回放句柄iPlayBack:" + iPlayBack);
+            
+            IntByReference nPos = new IntByReference(0);
+            boolean bret = hCNetSDK.NET_DVR_PlayBackControl_V40(iPlayBack, HCNetSDK.NET_DVR_PLAYGETPOS, null, 0, nPos.getPointer(), new IntByReference(0));            		              
+            if (bret)
+            {
+                System.out.println("回放进度:" + nPos.getValue());
+            }
+            else
+            {
+                System.out.println("获取回放进度失败,错误码: " + hCNetSDK.NET_DVR_GetLastError());
+                bEnd = true;
+            }
+            
+            //网络异常导致回放连接断开
+            if (nPos.getValue() > 100)
+            {
+            	//停止回放,释放资源
+                hCNetSDK.NET_DVR_StopPlayBack(iPlayBack);
+                iPlayBack = -1;
+                if (outputStream != null) {
+                    try {
+                        outputStream.close();
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                }
+                bEnd = true;
+                System.out.println("由于网络原因或DVR忙,回放异常终止!");
+            }
+            
+            //回放结束
+            if (nPos.getValue() == 100)
+            {
+            	//停止回放,释放资源
+                hCNetSDK.NET_DVR_StopPlayBack(iPlayBack);
+                iPlayBack = -1;
+                if (outputStream != null) {
+                    try {
+                        outputStream.close();
+                    } catch (IOException e) {
+                        // TODO Auto-generated catch block
+                        e.printStackTrace();
+                    }
+                }
+                bEnd = true;
+                System.out.println("按时间回放结束");
+            }
+         }
+    }
+
+
+
+    //获取IP通道
+    public static void getIPChannelInfo(int userID) {
+        IntByReference ibrBytesReturned = new IntByReference(0);//获取IP接入配置参数
+        HCNetSDK.NET_DVR_IPPARACFG_V40 m_strIpparaCfg = new HCNetSDK.NET_DVR_IPPARACFG_V40();
+        m_strIpparaCfg.write();
+        //lpIpParaConfig 接收数据的缓冲指针
+        Pointer lpIpParaConfig = m_strIpparaCfg.getPointer();
+        boolean bRet = hCNetSDK.NET_DVR_GetDVRConfig(userID, HCNetSDK.NET_DVR_GET_IPPARACFG_V40, 0, lpIpParaConfig, m_strIpparaCfg.size(), ibrBytesReturned);
+        m_strIpparaCfg.read();
+        System.out.println("起始数字通道号:" + m_strIpparaCfg.dwStartDChan);
+
+        for (int iChannum = 0; iChannum < m_strIpparaCfg.dwDChanNum; iChannum++) {
+            int channum = iChannum + m_strIpparaCfg.dwStartDChan;
+            m_strIpparaCfg.struStreamMode[iChannum].read();
+            if (m_strIpparaCfg.struStreamMode[iChannum].byGetStreamType == 0) {
+                m_strIpparaCfg.struStreamMode[iChannum].uGetStream.setType(HCNetSDK.NET_DVR_IPCHANINFO.class);
+                m_strIpparaCfg.struStreamMode[iChannum].uGetStream.struChanInfo.read();
+                if (m_strIpparaCfg.struStreamMode[iChannum].uGetStream.struChanInfo.byEnable == 1) {
+                    System.out.println("IP通道" + channum + "在线");
+                } else {
+                    System.out.println("IP通道" + channum + "不在线");
+                }
+            }
+        }
+    }
+
+    static class fPlayEScallback implements  HCNetSDK.FPlayESCallBack {
+        public void invoke(int lPreviewHandle, HCNetSDK.NET_DVR_PACKET_INFO_EX pstruPackInfo,Pointer pUser)
+        {
+            System.out.println("进入ES裸码流回调");
+            System.out.println(pstruPackInfo.dwPacketSize);
+            try {
+                fileLenth += pstruPackInfo.dwPacketSize;
+                fileOutputStream = new FileOutputStream(resultFileName,true);
+                //将字节写入文件
+                ByteBuffer buffers = pstruPackInfo.pPacketBuffer.getByteBuffer(0, pstruPackInfo.dwPacketSize);
+                byte[] bytes = new byte[pstruPackInfo.dwPacketSize];
+                buffers.rewind();
+                buffers.get(bytes);
+                fileOutputStream.write(bytes);
+            } catch (FileNotFoundException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    static  class playDataCallBack implements HCNetSDK.FPlayDataCallBack{
+        public void invoke(int lPlayHandle, int dwDataType, Pointer pBuffer, int dwBufSize, int dwUser)
+        {
+            //System.out.println("回放码流回调, 数据类型: " + dwDataType + ", 数据长度:" + dwBufSize);
+           
+            //将设备发送过来的回放码流数据写入文件
+            long offset = 0;
+            ByteBuffer buffers = pBuffer.getByteBuffer(offset, dwBufSize);
+            byte[] bytes = new byte[dwBufSize];
+            buffers.rewind();
+            buffers.get(bytes);
+            try {
+                outputStream.write(bytes);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    static class FRealDataCallBack implements HCNetSDK.FRealDataCallBack_V30 {
+        //预览回调
+        public void invoke(int lRealHandle, int dwDataType, ByteByReference pBuffer, int dwBufSize, Pointer pUser) {
+            //System.out.println("码流数据回调, 数据类型: " + dwDataType + ", 数据长度:" + dwBufSize);
+            //播放库解码
+            switch (dwDataType) {
+                case HCNetSDK.NET_DVR_SYSHEAD: //系统头
+                    if (!playControl.PlayM4_GetPort(m_lPort)) //获取播放库未使用的通道号
+                    {
+                        break;
+                    }
+                    if (dwBufSize > 0) {
+                        if (!playControl.PlayM4_SetStreamOpenMode(m_lPort.getValue(), PlayCtrl.STREAME_REALTIME))  //设置实时流播放模式
+                        {
+                            break;
+                        }
+                        if (!playControl.PlayM4_OpenStream(m_lPort.getValue(), pBuffer, dwBufSize, 1024 * 1024)) //打开流接口
+                        {
+                            break;
+                        }
+                        if (!playControl.PlayM4_Play(m_lPort.getValue(), null)) //播放开始
+                        {
+                            break;
+                        }
+
+                    }
+                case HCNetSDK.NET_DVR_STREAMDATA:   //码流数据
+                    if ((dwBufSize > 0) && (m_lPort.getValue() != -1)) {
+                        if (!playControl.PlayM4_InputData(m_lPort.getValue(), pBuffer, dwBufSize))  //输入流数据
+                        {
+                            break;
+                        }
+                    }
+            }
+        }
+    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}

+ 17 - 0
src/main/java/com/persagy/cameractl/temp/osSelect.java

@@ -0,0 +1,17 @@
+package com.persagy.cameractl.temp;
+
+/**
+ * @author jiangxin
+ * @create 2022-01-19-16:40
+ */
+public class osSelect {
+
+	public static boolean isLinux() {
+		return System.getProperty("os.name").toLowerCase().contains("linux");
+	}
+
+	public static boolean isWindows() {
+		return System.getProperty("os.name").toLowerCase().contains("windows");
+	}
+	
+}

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

@@ -7,6 +7,9 @@ public class Camera {
 	// 通道号  1~32表示模拟通道,9000系列混合型DVR和NVR等设备的IP通道从33开始(即程序用的通道号为33+通道号-1)。回放、实时播放、控制使用
 	public int channel;
 	
+	// 码流ID
+	public String streamId;
+	
 	// 码流类型 0:主码流 	1:子码流 	2:第三码流 参数不填,默认为子码流
 	public int streamType=1;
 

+ 19 - 0
src/main/java/com/persagy/cameractl/utils/CommonUtil.java

@@ -0,0 +1,19 @@
+package com.persagy.cameractl.utils;
+
+public class CommonUtil {
+
+	// SDK时间解析
+	public static String parseTime(int time) {
+		int dwYear = (time >> 26) + 2000;
+		int dwMonth = (time >> 22) & 15;
+		int dwDay = (time >> 17) & 31;
+		int dwHour = (time >> 12) & 31;
+		int dwMinute = (time >> 6) & 63;
+		int dwSecond = (time >> 0) & 63;
+
+		String sTime = String.format("%04d", dwYear) + String.format("%02d", dwMonth) + String.format("%02d", dwDay)
+				+ String.format("%02d", dwHour) + String.format("%02d", dwMinute) + String.format("%02d", dwSecond);
+		return sTime;
+	}
+
+}

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

@@ -59,6 +59,12 @@ public class OtherTools {
 		return (prefix != null && prefix != "" ? prefix + "," : "") + "厂家返回错误码:" + errCode;
 	}
 
+	/**
+	 * 包含mp4后缀
+	 * 
+	 * @return
+	 * @date 2022年6月23日 上午11:22:45
+	 */
 	public static String getVideoFilePath() {
 		String token = StringTools.getUUID();
 		return OtherTools.getVideoFilePathByT(token);

+ 17 - 0
src/main/java/com/persagy/cameractl/utils/osSelect.java

@@ -0,0 +1,17 @@
+package com.persagy.cameractl.utils;
+
+/**
+ * @author jiangxin
+ * @create 2022-01-19-16:40
+ */
+public class osSelect {
+
+	public static boolean isLinux() {
+		return System.getProperty("os.name").toLowerCase().contains("linux");
+	}
+
+	public static boolean isWindows() {
+		return System.getProperty("os.name").toLowerCase().contains("windows");
+	}
+	
+}

Plik diff jest za duży
+ 1 - 1
src/main/resources/application.yml


+ 6 - 0
src/main/resources/camera.json

@@ -0,0 +1,6 @@
+{
+	"index": {
+		"include_type_name": true,
+		"max_result_window": 2147483647
+	}
+}