diff --git a/sdkLog/SdkLog_1_W.log b/sdkLog/SdkLog_1_W.log index 228eb26..699e332 100644 --- a/sdkLog/SdkLog_1_W.log +++ b/sdkLog/SdkLog_1_W.log @@ -1,33 +1,4 @@ -[2025-08-18 11:30:56.314][DBG] CCoreGlobalCtrlBase::LoadDSo, HPR_LoadDSo Succ, Path[D:/workspace/inspect-nvr/lib/zlib1.dll], hHandleRet[1430257664] -[2025-08-18 11:30:56.314][INF] The COM:HCCoreBase ver is 6.1.4.15, 2020_03_05. Async:1. -[2025-08-18 11:30:56.314][INF] The COM:Core ver is 6.1.9.47, 2022_11_11. Async:1. -[2025-08-18 11:30:56.314][INF] This HCNetSDK ver is 6.1.9.47 Ver 2022_11_11. -[2025-08-18 11:33:15.465][INF] Login dev 192.168.1.250:8000. -[2025-08-18 11:33:15.466][INF] dwTotalNum[2048] -[2025-08-18 11:33:15.467][INF] Private connect 192.168.1.250:8000 sock=5244 this=0x2bc66ce4 cmd=0x10000 port=56125 -[2025-08-18 11:33:15.467][INF] LogonDev1 in[192.168.1.250:8000] -[2025-08-18 11:33:15.469][DBG] CCoreGlobalCtrlBase::LoadDSo, HPR_LoadDSo Succ, Path[D:/workspace/inspect-nvr/lib/libcrypto-1_1-x64.dll], hHandleRet[519634944] -[2025-08-18 11:33:15.469][DBG] Load [libcrypto-1_1-x64.dll] SUCC, Real Path[D:\workspace\inspect-nvr\lib\libcrypto-1_1-x64.dll] -[2025-08-18 11:33:15.473][DBG] CCoreGlobalCtrlBase::LoadDSo, HPR_LoadDSo Succ, Path[D:/workspace/inspect-nvr/lib/libssl-1_1-x64.dll], hHandleRet[1400373248] -[2025-08-18 11:33:15.473][DBG] Load [libssl-1_1-x64.dll] SUCC, Real Path[D:\workspace\inspect-nvr\lib\libssl-1_1-x64.dll] -[2025-08-18 11:33:15.473][INF] SSLTRANSAPI::IsAllAPILoaded, SSL_library_init Unload -[2025-08-18 11:33:15.473][INF] OpenSSL, Not All Function Loaded! -[2025-08-18 11:33:15.473][INF] SSLTRANSAPI::PrintVersion, OpenSSL version info [OpenSSL 1.1.1l 24 Aug 2021] -[2025-08-18 11:33:15.473][INF] CSSLTrans::SSLCtxInit, dwSSLVersion[6], m_fnTLSServerMethod -[2025-08-18 11:33:15.480][ERR] CSSLTrans::SSLTrans_CTX_Load_CA, invalid path[D:/workspace/inspect-nvr/lib/cert/\] -[2025-08-18 11:33:16.154][DBG] CComBase::Load, Load szDllPath[D:/workspace/inspect-nvr/lib/HCNetSDKCom/HCPreview.dll] SUCC -[2025-08-18 11:33:16.155][INF] AbilityAnalyze---Init-- start -[2025-08-18 11:33:16.156][ERR] AbilityAnalyze---open zip package error, package path D:/workspace/inspect-nvr/lib/LocalXml.zip -[2025-08-18 11:33:16.157][INF] The COM:Preview ver is 6.1.9.47, 2022_11_11. -[2025-08-18 11:33:16.168][INF] Private connect 192.168.1.250:8000 sock=5292 this=0x2bc66ce4 cmd=0x30009 port=56126 -[2025-08-18 11:36:41.425][INF] Login dev 192.168.1.250:8000. -[2025-08-18 11:36:41.437][INF] Private connect 192.168.1.250:8000 sock=5432 this=0x2bc66ce4 cmd=0x10000 port=56365 -[2025-08-18 11:36:41.437][INF] LogonDev1 in[192.168.1.250:8000] -[2025-08-18 11:36:41.503][INF] Private connect 192.168.1.250:8000 sock=5472 this=0x2bc66ce4 cmd=0x30009 port=56367 -[2025-08-18 11:37:10.523][INF] Private connect 192.168.1.250:8000 sock=5536 this=0x2bc66ce4 cmd=0x30200 port=56406 -[2025-08-18 11:37:18.684][INF] Private connect 192.168.1.250:8000 sock=5564 this=0x2bc66ce4 cmd=0x30200 port=56428 -[2025-08-18 11:37:21.152][INF] Private connect 192.168.1.250:8000 sock=5564 this=0x2bc66ce4 cmd=0x30009 port=56431 -[2025-08-18 11:37:27.623][INF] Private connect 192.168.1.250:8000 sock=5344 this=0x2bc66ce4 cmd=0x30009 port=56437 -[2025-08-18 11:37:32.428][INF] Private connect 192.168.1.250:8000 sock=5652 this=0x2bc66ce4 cmd=0x30200 port=56441 -[2025-08-18 11:37:38.720][INF] Private connect 192.168.1.250:8000 sock=5680 this=0x2bc66ce4 cmd=0x30009 port=56443 -[2025-08-18 11:39:11.090][INF] Private connect 192.168.1.250:8000 sock=5736 this=0x2bc66ce4 cmd=0x30009 port=56554 +[2025-09-03 14:03:42.300][DBG] CCoreGlobalCtrlBase::LoadDSo, HPR_LoadDSo Succ, Path[D:/workspace/inspect-nvr/lib/zlib1.dll], hHandleRet[1681326080] +[2025-09-03 14:03:42.300][INF] The COM:HCCoreBase ver is 6.1.4.15, 2020_03_05. Async:1. +[2025-09-03 14:03:42.300][INF] The COM:Core ver is 6.1.9.47, 2022_11_11. Async:1. +[2025-09-03 14:03:42.300][INF] This HCNetSDK ver is 6.1.9.47 Ver 2022_11_11. diff --git a/src/main/java/com/inspect/nvr/controller/CameraController.java b/src/main/java/com/inspect/nvr/controller/CameraController.java index 52fd6a6..6b9b0b2 100644 --- a/src/main/java/com/inspect/nvr/controller/CameraController.java +++ b/src/main/java/com/inspect/nvr/controller/CameraController.java @@ -1,18 +1,33 @@ package com.inspect.nvr.controller; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.inspect.nvr.domain.Infrared.Camera; import com.inspect.nvr.domain.Infrared.TemperatureData; +import com.inspect.nvr.domain.device.PtzControlParam; import com.inspect.nvr.hikVision.utils.AjaxResult; import com.inspect.nvr.service.DahuaService; import com.inspect.nvr.service.HikVisionService; +import com.inspect.nvr.service.IvsCameraService; +import com.inspect.nvr.utils.StringUtils; +import com.inspect.nvr.utils.redis.RedisService; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; +import org.springframework.util.StreamUtils; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.concurrent.*; +import java.util.function.Supplier; - +@Slf4j @Controller @RequestMapping public class CameraController { @@ -21,31 +36,39 @@ public class CameraController { private HikVisionService cameraService; @Resource private DahuaService dahuaService; + @Resource + IvsCameraService iVsCameraService; + @Resource + private RedisService redisService; //获取相机预置位列表--海康相机 @PostMapping("/hw/cameraYzwHikVision") @ResponseBody - public String cameraYzw(@RequestBody Camera camera) - { - return cameraService.cameraYzwHikVision(camera); + public String cameraYzw(@RequestBody Camera camera) { + return cameraService.cameraYzwHikVision(camera); } //获取红外测温规则温度值 (需要先跳转到红外测温规则预置位) @PostMapping("/hw/cameraHong") @ResponseBody @CrossOrigin - public AjaxResult cameraHong(@RequestBody Camera camera) { + public TemperatureData cameraHong(@RequestBody Camera camera) throws InterruptedException { + log.info("红外开始===================================》》》》》"); TemperatureData temperatureData = null; if(0 == camera.getCameraType()){ - temperatureData = cameraService.StartRemote(camera); + temperatureData = executeWithTimeout(() -> cameraService.StartRemote(camera), 5, TimeUnit.SECONDS); +// temperatureData = cameraService.StartRemote(camera); } else { temperatureData = dahuaService.StartRemote(camera); } + redisService.setCacheObject(camera.getIp() +'_'+ camera.getPresetId(), temperatureData, 200L, TimeUnit.SECONDS); + return temperatureData; + } + + - return AjaxResult.success().put("data", temperatureData); - } //同步相机信息 // @PostMapping("/getChannelList") // @ResponseBody @@ -53,4 +76,46 @@ public class CameraController { // return cameraService.getChannelList(nvrInfo); // } + @PostMapping("/hw/test") + @ResponseBody + @CrossOrigin + public AjaxResult cameraHong1(@RequestBody Camera camera) throws InterruptedException { + AjaxResult temperatureData = null; + // 海康威视:使用异步+超时控制 + log.info("测温结束================================================="); + temperatureData = executeWithTimeout(() -> cameraHong2(), 5, TimeUnit.SECONDS); + System.out.println("结束了"); + return temperatureData; + } + + + public AjaxResult cameraHong2() { + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + return AjaxResult.success(); + } + // 通用的超时执行方法 + private T executeWithTimeout(Supplier task, long timeout, TimeUnit unit) { + CompletableFuture future = CompletableFuture.supplyAsync(task); + + try { + return future.get(timeout, unit); + } catch (TimeoutException e) { + log.warn("任务执行超时,继续后续操作"); + future.cancel(true); // 尝试取消任务 + return null; // 或者返回默认值 + } catch (ExecutionException e) { + log.error("任务执行异常", e.getCause()); + return null; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + log.error("任务被中断", e); + return null; + } + } + + } diff --git a/src/main/java/com/inspect/nvr/domain/Infrared/Camera.java b/src/main/java/com/inspect/nvr/domain/Infrared/Camera.java index dcbe1b1..601b86c 100644 --- a/src/main/java/com/inspect/nvr/domain/Infrared/Camera.java +++ b/src/main/java/com/inspect/nvr/domain/Infrared/Camera.java @@ -48,4 +48,6 @@ public class Camera { private int cameraType; private int presetId; + + private String address; } diff --git a/src/main/java/com/inspect/nvr/domain/Infrared/TemperatureData.java b/src/main/java/com/inspect/nvr/domain/Infrared/TemperatureData.java index ce3de14..08f7986 100644 --- a/src/main/java/com/inspect/nvr/domain/Infrared/TemperatureData.java +++ b/src/main/java/com/inspect/nvr/domain/Infrared/TemperatureData.java @@ -9,8 +9,8 @@ import lombok.NoArgsConstructor; @NoArgsConstructor public class TemperatureData { - private float maxTemperature; // 最高温度 - private float minTemperature; // 最低温度 + private String maxTemperature; // 最高温度 + private String minTemperature; // 最低温度 private float avgTemperature; // 平均温度 private float temperatureDiff; // 温差 private int channel; // 通道号 diff --git a/src/main/java/com/inspect/nvr/hikVision/utils/jna/HikVisionUtils.java b/src/main/java/com/inspect/nvr/hikVision/utils/jna/HikVisionUtils.java index 5161a20..ee79190 100644 --- a/src/main/java/com/inspect/nvr/hikVision/utils/jna/HikVisionUtils.java +++ b/src/main/java/com/inspect/nvr/hikVision/utils/jna/HikVisionUtils.java @@ -1,8 +1,11 @@ package com.inspect.nvr.hikVision.utils.jna; +import lombok.extern.slf4j.Slf4j; + /** * 海康威视工具处理类 */ +@Slf4j public class HikVisionUtils { @@ -80,7 +83,7 @@ public class HikVisionUtils { m_strLoginInfo.wPort = port; m_strLoginInfo.bUseAsynLogin = false; //是否异步登录:0- 否,1- 是 m_strLoginInfo.write(); - + log.info("海康相机登录成功"); return m_strLoginInfo; } diff --git a/src/main/java/com/inspect/nvr/service/impl/DahuaServiceImpl.java b/src/main/java/com/inspect/nvr/service/impl/DahuaServiceImpl.java index 7494094..7c2a56e 100644 --- a/src/main/java/com/inspect/nvr/service/impl/DahuaServiceImpl.java +++ b/src/main/java/com/inspect/nvr/service/impl/DahuaServiceImpl.java @@ -44,6 +44,8 @@ public class DahuaServiceImpl implements DahuaService { @Autowired private fSnapReceiveCB snapReceiveCB; + private static final Object captureLock = new Object(); + /** * 登录大华设备 * @param nvrInfo @@ -89,6 +91,7 @@ public class DahuaServiceImpl implements DahuaService { */ @Override public TemperatureData StartRemote(Camera camera) { + log.info("大华实时测温入口================================================="); Object storedObj = redisService.redisTemplate.opsForValue().get(camera.getIp() + "_m_hLoginHandle"); // 2. 进行空值和类型判断 if (StringUtils.isNotNull(storedObj)) { @@ -100,6 +103,7 @@ public class DahuaServiceImpl implements DahuaService { } // 3. 安全转换并创建LLong对象 if (ObjectUtil.isEmpty(m_hLoginHandle)) { + log.info("大华摄像机登录 ip:{}",camera.getIp()); NvrInfo nvrInfo = new NvrInfo(); nvrInfo.setNvrIp(camera.getIp()); nvrInfo.setServerPort(camera.getPort()); @@ -107,15 +111,13 @@ public class DahuaServiceImpl implements DahuaService { nvrInfo.setPassword(camera.getPassword()); login(nvrInfo); m_hLoginHandle = new NetSDKLib.LLong((Long) redisService.redisTemplate.opsForValue().get(camera.getIp() + "_m_hLoginHandle")); - log.info("相机:m_hLoginHandle" + camera.getNvrip() + "m_hLoginHandle" + m_hLoginHandle); } // 1. 初始化输入结构体 - + log.info("开始实时测温================================================="); + log.info("cameraip:{},PresetId:{}",camera.getIp(),camera.getPresetId()); NetSDKLib.NET_IN_RADIOMETRY_GETTEMPER netIn = new NetSDKLib.NET_IN_RADIOMETRY_GETTEMPER(); - - // 设置条件参数 netIn.stCondition.nPresetId = camera.getPresetId(); netIn.stCondition.nRuleId = 1; @@ -158,16 +160,26 @@ public class DahuaServiceImpl implements DahuaService { float fTemperMax = stTempInfo.fTemperMax; System.out.println("温度最大值: " + fTemperMax); TemperatureData data = new TemperatureData( - stTempInfo.fTemperMax, - stTempInfo.fTemperMin, + String.valueOf(stTempInfo.fTemperMax), + String.valueOf(stTempInfo.fTemperMin), stTempInfo.fTemperAver, stTempInfo.fTemperStd, netIn.stCondition.nPresetId, netIn.stCondition.nRuleId ); + boolean b = dhNetSDK.CLIENT_Logout(m_hLoginHandle); + if (b) { + redisService.redisTemplate.opsForValue().getOperations().delete(camera.getIp() + "_m_hLoginHandle"); + System.out.println("摄像机登出"); + } return data; } System.out.println("大华-获取设备参数失败,错误码:" + ToolKits.getErrorCodePrint(dhNetSDK.CLIENT_GetLastError())); + boolean b = dhNetSDK.CLIENT_Logout(m_hLoginHandle); + if (b) { + redisService.redisTemplate.opsForValue().getOperations().delete(camera.getIp() + "_m_hLoginHandle"); + System.out.println("摄像机登出"); + } return null; } @@ -220,103 +232,104 @@ public class DahuaServiceImpl implements DahuaService { */ @Override public ByteArrayInputStream Picture(Camera camera) { - Object storedObj = redisService.redisTemplate.opsForValue().get(camera.getIp() + "_m_hLoginHandle"); - // 2. 进行空值和类型判断 - if (StringUtils.isNotNull(storedObj)) { - Long storedValue = (Long) storedObj; - m_hLoginHandle = new NetSDKLib.LLong(storedValue); - } else { - //m_hLoginHandle为空 - m_hLoginHandle = null; - } - if (ObjectUtil.isEmpty(m_hLoginHandle)) { - NvrInfo nvrInfo = new NvrInfo(); - nvrInfo.setNvrIp(camera.getIp()); - nvrInfo.setServerPort(camera.getPort()); - nvrInfo.setAccount(camera.getUserName()); - nvrInfo.setPassword(camera.getPassword()); - login(nvrInfo); - m_hLoginHandle = new NetSDKLib.LLong((Long) redisService.redisTemplate.opsForValue().get(camera.getIp() + "_m_hLoginHandle")); - log.info("相机:m_hLoginHandle" + camera.getIp() + "m_hLoginHandle" + m_hLoginHandle); - } - // 2. 准备抓图参数 - NetSDKLib.SNAP_PARAMS snapParams = new NetSDKLib.SNAP_PARAMS(); - snapParams.Channel = camera.getChannel() - 1; // channel - snapParams.mode = 0; // capture picture mode - snapParams.Quality = 3; // picture quality - snapParams.InterSnap = 0; // timer capture picture time interval - snapParams.CmdSerial = 0; // request serial - IntByReference intByReference = new IntByReference(camera.getChannel() - 1); - dhNetSDK.CLIENT_SetSnapRevCallBack(null, null); - - // 3. 准备接收回调的数据 - final byte[][] imageBytes = new byte[1][]; - final CountDownLatch latch = new CountDownLatch(1); - - // 4. 创建回调 - fSnapReceiveCB snapCallback = new fSnapReceiveCB() { - @Override - public void invoke(NetSDKLib.LLong lLoginID, Pointer pBuf, int RevLen, - int EncodeType, int CmdSerial, Pointer dwUser) { - try { - if (pBuf != null && RevLen > 0) { - imageBytes[0] = pBuf.getByteArray(0, RevLen); + synchronized (captureLock) { + Object storedObj = redisService.redisTemplate.opsForValue().get(camera.getIp() + "_m_hLoginHandle"); + // 2. 进行空值和类型判断 + if (StringUtils.isNotNull(storedObj)) { + Long storedValue = (Long) storedObj; + m_hLoginHandle = new NetSDKLib.LLong(storedValue); + } else { + //m_hLoginHandle为空 + m_hLoginHandle = null; + } + if (ObjectUtil.isEmpty(m_hLoginHandle)) { + NvrInfo nvrInfo = new NvrInfo(); + nvrInfo.setNvrIp(camera.getIp()); + nvrInfo.setServerPort(camera.getPort()); + nvrInfo.setAccount(camera.getUserName()); + nvrInfo.setPassword(camera.getPassword()); + login(nvrInfo); + m_hLoginHandle = new NetSDKLib.LLong((Long) redisService.redisTemplate.opsForValue().get(camera.getIp() + "_m_hLoginHandle")); + log.info("相机:m_hLoginHandle" + camera.getIp() + "m_hLoginHandle" + m_hLoginHandle); + } + // 2. 准备抓图参数 + NetSDKLib.SNAP_PARAMS snapParams = new NetSDKLib.SNAP_PARAMS(); + snapParams.Channel = camera.getChannel() - 1; // channel + snapParams.mode = 0; // capture picture mode + snapParams.Quality = 3; // picture quality + snapParams.InterSnap = 0; // timer capture picture time interval + snapParams.CmdSerial = 0; // request serial + IntByReference intByReference = new IntByReference(camera.getChannel() - 1); + dhNetSDK.CLIENT_SetSnapRevCallBack(null, null); + + // 3. 准备接收回调的数据 + final byte[][] imageBytes = new byte[1][]; + final CountDownLatch latch = new CountDownLatch(1); + + // 4. 创建回调 + fSnapReceiveCB snapCallback = new fSnapReceiveCB() { + @Override + public void invoke(NetSDKLib.LLong lLoginID, Pointer pBuf, int RevLen, + int EncodeType, int CmdSerial, Pointer dwUser) { + try { + if (pBuf != null && RevLen > 0) { + imageBytes[0] = pBuf.getByteArray(0, RevLen); + } + } finally { + latch.countDown(); // 确保无论如何都会释放锁 } - } finally { - latch.countDown(); // 确保无论如何都会释放锁 } - } - }; - - // 5. 设置回调并执行抓图 - dhNetSDK.CLIENT_SetSnapRevCallBack(snapCallback, null); - if (!dhNetSDK.CLIENT_SnapPictureEx(m_hLoginHandle, snapParams, intByReference)) { - log.error("CLIENT_SnapPictureEx Failed! " + - ToolKits.getErrorCodePrint(dhNetSDK.CLIENT_GetLastError())); - return null; - } + }; - // 6. 等待回调完成 - try { - if (!latch.await(5, TimeUnit.SECONDS)) { - log.error("等待图片回调超时"); + // 5. 设置回调并执行抓图 + dhNetSDK.CLIENT_SetSnapRevCallBack(snapCallback, null); + if (!dhNetSDK.CLIENT_SnapPictureEx(m_hLoginHandle, snapParams, intByReference)) { + log.error("CLIENT_SnapPictureEx Failed! " + + ToolKits.getErrorCodePrint(dhNetSDK.CLIENT_GetLastError())); return null; } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - log.error("等待图片回调被中断", e); - return null; - } - // 7. 如果获取到图片数据,保存到 D:\pic 目录 - if (imageBytes[0] != null) { + + // 6. 等待回调完成 try { - // 确保目录存在 - File picDir = new File("D:\\pic"); - if (!picDir.exists()) { - picDir.mkdirs(); // 如果目录不存在,创建它 + if (!latch.await(5, TimeUnit.SECONDS)) { + log.error("等待图片回调超时"); + return null; } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + log.error("等待图片回调被中断", e); + return null; + } + // 7. 如果获取到图片数据,保存到 D:\pic 目录 + if (imageBytes[0] != null) { + try { + // 确保目录存在 + File picDir = new File("D:\\pic"); + if (!picDir.exists()) { + picDir.mkdirs(); // 如果目录不存在,创建它 + } - // 生成文件名(例如:camera_ip + timestamp) - String fileName = "D:\\pic\\" + camera.getIp() + "_" + System.currentTimeMillis() + ".jpg"; + // 生成文件名(例如:camera_ip + timestamp) + String fileName = "D:\\pic\\" + camera.getIp() + "_" + System.currentTimeMillis() + ".jpg"; - // 保存图片 - FileOutputStream fos = new FileOutputStream(fileName); - fos.write(imageBytes[0]); - fos.close(); + // 保存图片 + FileOutputStream fos = new FileOutputStream(fileName); + fos.write(imageBytes[0]); + fos.close(); - log.info("图片已保存至: " + fileName); - } catch (IOException e) { - log.error("保存图片失败", e); + log.info("图片已保存至: " + fileName); + } catch (IOException e) { + log.error("保存图片失败", e); + } } + boolean bTemp = dhNetSDK.CLIENT_Logout(m_hLoginHandle); + if (bTemp) { + redisService.redisTemplate.opsForValue().getOperations().delete(camera.getIp() + "_m_hLoginHandle"); + log.info("登出成功"); + } + return imageBytes[0] != null ? new ByteArrayInputStream(imageBytes[0]) : null; } - boolean bTemp = dhNetSDK.CLIENT_Logout(m_hLoginHandle); - if (bTemp){ - redisService.redisTemplate.opsForValue().getOperations().delete(camera.getIp() + "_m_hLoginHandle"); - log.info("登出成功"); - } - // 7. 返回结果 - return imageBytes[0] != null ? new ByteArrayInputStream(imageBytes[0]) : null; } diff --git a/src/main/java/com/inspect/nvr/service/impl/HikVisionServiceImpl.java b/src/main/java/com/inspect/nvr/service/impl/HikVisionServiceImpl.java index 01bf954..eb95cdf 100644 --- a/src/main/java/com/inspect/nvr/service/impl/HikVisionServiceImpl.java +++ b/src/main/java/com/inspect/nvr/service/impl/HikVisionServiceImpl.java @@ -58,6 +58,7 @@ import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -122,7 +123,7 @@ public class HikVisionServiceImpl implements HikVisionService { } - /** + /** * 设备登录V40 与V30功能一致 */ public AjaxResult login_V40(NvrInfo nvrInfo) { @@ -171,118 +172,105 @@ public class HikVisionServiceImpl implements HikVisionService { } } - //摄像头登录方法 //实时测温接口,获取最高温和最低温 public TemperatureData StartRemote(Camera camera) { + int result = 0; + TemperatureData temperatureData = null; - if (camera.getLUserID() != 0) { + try { - // 1. 登录设备 - HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = HikVisionUtils.login_V40(camera.getIp(), (short) camera.getPort(), camera.getUserName(), camera.getPassword()); - HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40(); - int lUserID = hcNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo); + log.info("实时测温入口================================================="); + if (camera.getLUserID() != 0) { + log.info("海康摄像机登录 ip:{}", camera.getIp()); + // 1. 登录设备 + HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = HikVisionUtils.login_V40(camera.getIp(), (short) camera.getPort(), camera.getUserName(), camera.getPassword()); + HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40(); + int lUserID = hcNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo); + + if (lUserID == -1) { + int errorCode = hcNetSDK.NET_DVR_GetLastError(); + String errorMsg = hcNetSDK.NET_DVR_GetErrorMsg(new IntByReference(errorCode)); + log.error("登录设备失败,错误码为:{},错误信息为:{}", errorCode, errorMsg); + } + camera.setLUserID(lUserID); + } - if (lUserID == -1) { + log.info("开始实时测温================================================="); + // 2. 设置测温参数 + HCNetSDK.NET_DVR_REALTIME_THERMOMETRY_COND cond = new HCNetSDK.NET_DVR_REALTIME_THERMOMETRY_COND(); + cond.dwSize = cond.size(); + cond.dwChan = camera.getChannel();// 通道号 + cond.byRuleID = 1; // 规则ID + cond.byMode = 1; // 测温模式 + cond.wInterval = 10; // 间隔 + cond.byRes2 = new byte[32]; + Arrays.fill(cond.byRes2, (byte) 0); + cond.write(); // 手动同步结构体到内存 + CompletableFuture temperatureFuture = new CompletableFuture<>(); + // 3. 启动远程测温 + Pointer lpInBuffer = cond.getPointer(); + int dwInBufferSize = cond.size(); + result = hcNetSDK.NET_DVR_StartRemoteConfig( + camera.getLUserID(), + hcNetSDK.NET_DVR_GET_REALTIME_THERMOMETRY, + lpInBuffer, + dwInBufferSize, + new HikFRemoteConfigCallBack_imp() { + @Override + public void invoke(int dwType, Pointer lpBuffer, int dwBufLen, Pointer pUserData) { + System.out.println("回调收到数据,类型: " + dwType + ", 长度: " + dwBufLen); + HCNetSDK.NET_DVR_THERMOMETRY_UPLOAD thermometryData = new HCNetSDK.NET_DVR_THERMOMETRY_UPLOAD(); + int structSize = thermometryData.size(); + if (dwBufLen < structSize) { + System.out.println("缓冲区长度不足,期望: " + structSize + ", 实际: " + dwBufLen); + return; + } + Pointer structurePointer = thermometryData.getPointer(); + structurePointer.write(0, lpBuffer.getByteArray(0, structSize), 0, structSize); + thermometryData.read(); // 解析数据到结构体字段 + HCNetSDK.NET_DVR_LINEPOLYGON_THERM_CFG struLinePolygonThermCfg = thermometryData.struLinePolygonThermCfg; + System.out.println("规则ID: " + thermometryData.byRuleID); + System.out.println("最高温度: " + struLinePolygonThermCfg.fMaxTemperature); + System.out.println("最低温度: " + struLinePolygonThermCfg.fMinTemperature); + System.out.println("平均温度: " + struLinePolygonThermCfg.fAverageTemperature); + System.out.println("温差: " + struLinePolygonThermCfg.fTemperatureDiff); + System.out.println("通道号: " + thermometryData.dwChan); + System.out.println("-----------------------------------------------------------"); + // 封装所有温度数据 + TemperatureData data = new TemperatureData( + String.valueOf(struLinePolygonThermCfg.fMaxTemperature), + String.valueOf(struLinePolygonThermCfg.fMinTemperature), + struLinePolygonThermCfg.fAverageTemperature, + struLinePolygonThermCfg.fTemperatureDiff, + thermometryData.dwChan, + thermometryData.byRuleID + ); + temperatureFuture.complete(data); // 返回完整数据 + } + }, + null + ); + log.info("测温结束================================================="); + if (result == -1) { int errorCode = hcNetSDK.NET_DVR_GetLastError(); String errorMsg = hcNetSDK.NET_DVR_GetErrorMsg(new IntByReference(errorCode)); - log.error("登录设备失败,错误码为:{},错误信息为:{}", errorCode, errorMsg); + log.error("启动远程测温失败,错误码为:{},错误信息为:{}", errorCode, errorMsg); } - camera.setLUserID(lUserID); - } - - - // 2. 设置测温参数 - HCNetSDK.NET_DVR_REALTIME_THERMOMETRY_COND cond = new HCNetSDK.NET_DVR_REALTIME_THERMOMETRY_COND(); - cond.dwSize = cond.size(); - cond.dwChan = camera.getChannel();// 通道号 - cond.byRuleID = 1; // 规则ID - cond.byMode = 1; // 测温模式 - cond.wInterval = 10; // 间隔 - cond.byRes2 = new byte[32]; - Arrays.fill(cond.byRes2, (byte) 0); - - cond.write(); // 手动同步结构体到内存 - - CompletableFuture temperatureFuture = new CompletableFuture<>(); - - // 3. 启动远程测温 - Pointer lpInBuffer = cond.getPointer(); - int dwInBufferSize = cond.size(); - - int result = hcNetSDK.NET_DVR_StartRemoteConfig( - camera.getLUserID(), - hcNetSDK.NET_DVR_GET_REALTIME_THERMOMETRY, - lpInBuffer, - dwInBufferSize, - new HikFRemoteConfigCallBack_imp() { - @Override - public void invoke(int dwType, Pointer lpBuffer, int dwBufLen, Pointer pUserData) { - - - System.out.println("回调收到数据,类型: " + dwType + ", 长度: " + dwBufLen); - - HCNetSDK.NET_DVR_THERMOMETRY_UPLOAD thermometryData = new HCNetSDK.NET_DVR_THERMOMETRY_UPLOAD(); - int structSize = thermometryData.size(); - - if (dwBufLen < structSize) { - System.out.println("缓冲区长度不足,期望: " + structSize + ", 实际: " + dwBufLen); - return; - } - Pointer structurePointer = thermometryData.getPointer(); - structurePointer.write(0, lpBuffer.getByteArray(0, structSize), 0, structSize); - thermometryData.read(); // 解析数据到结构体字段 - HCNetSDK.NET_DVR_LINEPOLYGON_THERM_CFG struLinePolygonThermCfg = thermometryData.struLinePolygonThermCfg; - System.out.println("规则ID: " + thermometryData.byRuleID); - System.out.println("最高温度: " + struLinePolygonThermCfg.fMaxTemperature); - - - System.out.println("最低温度: " + struLinePolygonThermCfg.fMinTemperature); - System.out.println("平均温度: " + struLinePolygonThermCfg.fAverageTemperature); - System.out.println("温差: " + struLinePolygonThermCfg.fTemperatureDiff); - System.out.println("通道号: " + thermometryData.dwChan); - System.out.println("-----------------------------------------------------------"); - - // 封装所有温度数据 - TemperatureData data = new TemperatureData( - struLinePolygonThermCfg.fMaxTemperature, - struLinePolygonThermCfg.fMinTemperature, - struLinePolygonThermCfg.fAverageTemperature, - struLinePolygonThermCfg.fTemperatureDiff, - thermometryData.dwChan, - thermometryData.byRuleID - ); - - temperatureFuture.complete(data); // 返回完整数据 - - } - }, - null - ); - - if (result == -1) { - int errorCode = hcNetSDK.NET_DVR_GetLastError(); - String errorMsg = hcNetSDK.NET_DVR_GetErrorMsg(new IntByReference(errorCode)); - log.error("启动远程测温失败,错误码为:{},错误信息为:{}", errorCode, errorMsg); - } - - TemperatureData temperatureData = null; - try { temperatureData = temperatureFuture.get(); } catch (InterruptedException e) { throw new RuntimeException(e); } catch (ExecutionException e) { throw new RuntimeException(e); - } - - - //关闭实时测温 - boolean i = StopRemote(result); - if (i) { - log.info("关闭实时测温 {}", true); + } finally { + log.info("关闭实时测温result值 {}", result); + //关闭实时测温 + boolean i = StopRemote(result); + if (i) { + log.info("关闭实时测温成功 {}", true); + } } return temperatureData; - } //关闭实时测温 @@ -328,7 +316,7 @@ public class HikVisionServiceImpl implements HikVisionService { } - //抓图 + //抓图 单独测试 未使用 @Override public Camera cameraPictrue(Camera camera) throws Exception { log.info(camera.getIp() + "摄像头抓图"); @@ -351,13 +339,21 @@ public class HikVisionServiceImpl implements HikVisionService { dvrJpegpara.wPicSize = 0xff; // 0xff表示最高分辨率 dvrJpegpara.wPicQuality = 2; // 图像质量(1-6,1最高) // 2. 创建临时存储目录(系统临时目录更安全) - Path tempDir = Paths.get(System.getProperty("java.io.tmpdir"), "hik_capture"); - if (!Files.exists(tempDir)) { - Files.createDirectories(tempDir); +// Path tempDir = Paths.get(System.getProperty("java.io.tmpdir"), "hik_capture"); +// if (!Files.exists(tempDir)) { +// Files.createDirectories(tempDir); +// } +// // 3. 生成唯一文件名(IP+时间戳) +// String fileName = String.format("%s_%s.jpg", camera.getIp(), DateUtils.dateTimeNow("yyyyMMddHHmmss")); +// Path tempImagePath = tempDir.resolve(fileName); + // 确保目录存在 + File picDir = new File("D:\\pic"); + if (!picDir.exists()) { + picDir.mkdirs(); // 如果目录不存在,创建它 } - // 3. 生成唯一文件名(IP+时间戳) - String fileName = String.format("%s_%s.jpg", camera.getIp(), DateUtils.dateTimeNow("yyyyMMddHHmmss")); - Path tempImagePath = tempDir.resolve(fileName); + // 生成文件名(例如:camera_ip + timestamp) + String fileName = "D:\\pic\\" + camera.getIp() + "_" + System.currentTimeMillis() + ".jpg"; + Path tempImagePath = Paths.get(fileName); // 4. 执行抓图(注意:海康SDK要求Windows风格的路径) boolean success = hcNetSDK.NET_DVR_CaptureJPEGPicture(camera.getLUserID(), 2, dvrJpegpara, tempImagePath.toString().getBytes("GBK")); // 海康设备通常需要GBK编码 @@ -423,16 +419,16 @@ public class HikVisionServiceImpl implements HikVisionService { //3:调取摄像头实时测温功能,获取最高温和最低温 TemperatureData temperatureData = StartRemote(camera); - double maxTemperature = temperatureData.getMaxTemperature(); - double minTemperature = temperatureData.getMinTemperature(); +// double maxTemperature = temperatureData.getMaxTemperature(); +// double minTemperature = temperatureData.getMinTemperature(); temperatureData.getAvgTemperature(); temperatureData.getTemperatureDiff(); InputStream inputStream = downloadFtp(camera.getUlr()); //传入照片流,最大值最小温度值,反算温度矩阵 - float[][] floats = tempCount.countTemp(inputStream, maxTemperature, minTemperature); - infraredInfo.setTemperatureMatrix(floats); +// float[][] floats = tempCount.countTemp(inputStream, maxTemperature, minTemperature); +// infraredInfo.setTemperatureMatrix(floats); //4:画框标注,保存到ftp @@ -1155,8 +1151,6 @@ public class HikVisionServiceImpl implements HikVisionService { } - - //预置位获取-海康 @Override public String cameraYzwHikVision(Camera camera) { @@ -1212,7 +1206,4 @@ public class HikVisionServiceImpl implements HikVisionService { } - - - } diff --git a/src/main/java/com/inspect/nvr/service/impl/IvsCameraServiceImpl.java b/src/main/java/com/inspect/nvr/service/impl/IvsCameraServiceImpl.java index e397c18..8d4bf35 100644 --- a/src/main/java/com/inspect/nvr/service/impl/IvsCameraServiceImpl.java +++ b/src/main/java/com/inspect/nvr/service/impl/IvsCameraServiceImpl.java @@ -1,8 +1,11 @@ package com.inspect.nvr.service.impl; import cn.hutool.core.util.ObjectUtil; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.inspect.nvr.controller.CameraController; import com.inspect.nvr.domain.Infrared.Camera; import com.inspect.nvr.domain.Infrared.NvrInfo; +import com.inspect.nvr.domain.Infrared.TemperatureData; import com.inspect.nvr.domain.device.*; import com.inspect.nvr.hikVision.utils.AjaxResult; import com.inspect.nvr.hikVision.utils.StringUtils; @@ -23,14 +26,14 @@ import org.springframework.util.StreamUtils; import javax.annotation.Resource; import java.io.ByteArrayInputStream; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; +import java.util.*; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @Slf4j @@ -50,6 +53,8 @@ public class IvsCameraServiceImpl implements IvsCameraService { @Autowired private DahuaService dahuaService; + @Autowired + private CameraController cameraController; @Override public IvsPresetListView ptzPresetList(String cameraCode, String domainCode) { @@ -79,79 +84,114 @@ public class IvsCameraServiceImpl implements IvsCameraService { .build(); } Camera camera = new Camera(); - //赋值 -// camera.setIp("192.168.1.231"); -// camera.setPort(8000); -// camera.setUserName("admin"); -// camera.setPassword("2016.h.BD"); -// camera.setChannel(11); -// camera.setPointNum(210); - //目前写死的 nvr信息 cameraType=0海康 1大华 - String ip = "192.168.1.231"; - int port = 8000; - int channel = 11; - int pointNum = 210; - String username = "admin"; - String password = "sshw1234"; - int cameraType = 0; String[] splitArray = param.getAddress().split(":"); - if (splitArray.length >= 5) { - log.info("PTZ_CONTROL CORRECT CONFIG"); - ip = splitArray[0]; - port = Integer.parseInt(splitArray[1]); - channel = Integer.parseInt(splitArray[2]); - pointNum = Integer.parseInt(splitArray[3]); - cameraType = Integer.parseInt(splitArray[4]); - username = splitArray[5]; - password = splitArray[6]; - } + //给camera赋值 + //cameraType=0海康 1大华 + String ip = splitArray[0]; + int port = Integer.parseInt(splitArray[1]); + int channel = Integer.parseInt(splitArray[2]); + int pointNum = Integer.parseInt(splitArray[3]); + String username = splitArray[5]; + String password = splitArray[6]; + int cameraType = Integer.parseInt(splitArray[4]); camera.setIp(ip); camera.setPort(port); camera.setChannel(channel); camera.setPointNum(pointNum); camera.setUserName(username); camera.setPassword(password); - log.info("PTZ_CONTROL ip:" + ip + " port:" + port + "username:" + username + "password" + password + " channel:" + channel + " pointNum:" + pointNum); - log.info("PTZ_CONTROL Type" + cameraType); + log.info("预置位NVR:" + ip + " channel:" + channel + " pointNum:" + pointNum + " cameraType:" + cameraType); + //给camera赋值结束 + PtzControlResult ptzControlResult = ptzDetailControl(camera, cameraType); + + try { + //等待5s开始调用红外 + Thread.sleep(5000); + Camera cameraHw = new Camera(); + cameraHw.setAddress(param.getAddress()); + cameraHw.setIp(splitArray[7]); + cameraHw.setPort(Integer.parseInt(splitArray[8])); + cameraHw.setChannel(Integer.parseInt(splitArray[9])); + cameraHw.setPresetId(Integer.parseInt(splitArray[3])); + cameraHw.setCameraType(Integer.parseInt(splitArray[4])); + cameraHw.setUserName(splitArray[10]); + cameraHw.setPassword(splitArray[11]); + //获取红外温度 + retry(cameraHw,camera, cameraType); + } catch (Exception e) { +// throw new RuntimeException(e); + } + return ptzControlResult; + + } + + public PtzControlResult ptzDetailControl(Camera camera,int cameraType) { //大华预置位跳转 + PtzControlResult ptzControlResult = null; if (ObjectUtil.equals(cameraType, 1)) { - log.info("开始登录大华摄像头 进行跳转预置位"); + log.info("开始登录大华NVR 进行跳转预置位"); String ajaxResult = dahuaService.cameraControl(camera, 0, 0, 0); - PtzControlResult ptzControlResult = PtzControlResult.builder() + ptzControlResult = PtzControlResult.builder() .resultCode(ajaxResult) .build(); - return ptzControlResult; - } - //海康预置位跳转 - log.info("开始登录海康摄像头 进行跳转预置位"); - lUserID = (Integer) redisService.redisTemplate.opsForValue().get(camera.getIp() + "_userId"); - if (ObjectUtil.isEmpty(lUserID)) { - NvrInfo nvrInfo = new NvrInfo(); - nvrInfo.setNvrIp(camera.getIp()); - nvrInfo.setServerPort(camera.getPort()); - nvrInfo.setAccount(camera.getUserName()); - nvrInfo.setPassword(camera.getPassword()); - login_V40(nvrInfo); + } else { + //海康预置位跳转 + log.info("开始登录海康NVR 进行跳转预置位"); lUserID = (Integer) redisService.redisTemplate.opsForValue().get(camera.getIp() + "_userId"); - log.info("相机:lUserID" + camera.getIp() + "_userId" + lUserID); - } - - - //参数:登录令牌,通道号,预置位跳转,跳转的预置位码 - boolean gotoPreset = hcNetSDK.NET_DVR_PTZPreset_Other(lUserID, camera.getChannel(), HCNetSDK.GOTO_PRESET, camera.getPointNum()); - if (!gotoPreset) { - log.error("海康-获取设备预置位跳转设备参数失败,错误码:" + hcNetSDK.NET_DVR_GetLastError()); - return PtzControlResult.builder() - .resultCode("-1") + if (ObjectUtil.isEmpty(lUserID)) { + NvrInfo nvrInfo = new NvrInfo(); + nvrInfo.setNvrIp(camera.getIp()); + nvrInfo.setServerPort(camera.getPort()); + nvrInfo.setAccount(camera.getUserName()); + nvrInfo.setPassword(camera.getPassword()); + login_V40(nvrInfo); + lUserID = (Integer) redisService.redisTemplate.opsForValue().get(camera.getIp() + "_userId"); + log.info("相机:lUserID" + camera.getIp() + "_userId" + lUserID); + } + //参数:登录令牌,通道号,预置位跳转,跳转的预置位码 + boolean gotoPreset = hcNetSDK.NET_DVR_PTZPreset_Other(lUserID, camera.getChannel(), HCNetSDK.GOTO_PRESET, camera.getPointNum()); + if (!gotoPreset) { + log.error("海康-获取设备预置位跳转设备参数失败,错误码:" + hcNetSDK.NET_DVR_GetLastError()); + return PtzControlResult.builder() + .resultCode("-1") + .build(); + } else { + log.info("海康-成功跳转到预置位!"); + } + ptzControlResult = PtzControlResult.builder() + .resultCode("0") .build(); - } else { - log.info("海康-成功跳转到预置位!"); } - PtzControlResult ptzControlResult = PtzControlResult.builder() - .resultCode("0") - .build(); return ptzControlResult; - + } + /** + * 大华红外读数多次读取 + * @param camera + * @return + */ + public TemperatureData retry(Camera camera,Camera nvrCamera,int cameraType){ + //添加重试机制 + final int MAX_RETRIES = 3; // 最大重试次数 + boolean success = false; + int retryCount = 0; + while (!success && retryCount < MAX_RETRIES) { + try { + retryCount++; + log.info("第{}次尝试读取红外", retryCount); + TemperatureData temperatureData = cameraController.cameraHong(camera); + if(StringUtils.isNull(temperatureData)){ + log.warn("第{}次读取红外失败", retryCount); + ptzDetailControl(nvrCamera,cameraType); + Thread.sleep(3000); // 等待2秒后重试 + } else { + success = true; + return temperatureData; + } + } catch (Exception e) { + log.error("第{}次抓图失败: {}", retryCount, e.getMessage()); + } + } + return null; } //拍照 @@ -189,6 +229,12 @@ public class IvsCameraServiceImpl implements IvsCameraService { return snapshotInfoListResult; } + /** + * 下载图片 + * + * @param fileSessionId + * @return + */ @Override public ByteArrayInputStream downloadFile(String fileSessionId) { final String rawString = StringHexConverter.fromHex(fileSessionId); @@ -201,22 +247,9 @@ public class IvsCameraServiceImpl implements IvsCameraService { } } String[] cameraAddressInfos = rawString.split((":")); -// if (cameraAddressInfos.length != 7) { -// log.error("DOWNLOAD_FILE ADDRESS INFO ERROR rawString: {}", rawString); -// try { -// return new ByteArrayInputStream(loadDefaultImage()); -// } catch (IOException e) { -// throw new RuntimeException("测试环境生成错误图片失败2", e); -// } -// } // 从nvr或者camera下载图片, 开发中 Camera camera = new Camera(); //赋值 -// camera.setIp("192.168.1.231"); -// camera.setPort(8000); -// camera.setUserName("admin"); -// camera.setPassword("2016.h.BD"); -// camera.setChannel(11); log.info("DOWNLOAD_FILE ip: {}, port: {}, channel: {}, pointName: {},cameraType: {}, username: {}, password: {}", cameraAddressInfos[0], cameraAddressInfos[1], @@ -232,53 +265,64 @@ public class IvsCameraServiceImpl implements IvsCameraService { camera.setCameraType(Integer.parseInt(cameraAddressInfos[4])); camera.setUserName(cameraAddressInfos[5]); camera.setPassword(cameraAddressInfos[6]); - if (ObjectUtil.equals(camera.getCameraType(), 1)){ + if (ObjectUtil.equals(camera.getCameraType(), 1)) { log.info("大华相机拍照"); ByteArrayInputStream picture = dahuaService.Picture(camera); return picture; - } - //从redis中获取lUserID(存在时间200) - lUserID = (Integer) redisService.redisTemplate.opsForValue().get(camera.getIp() + "_userId"); - //判断lUserID是否为空 - if (ObjectUtil.isEmpty(lUserID)) { - //重新登录获取lUserID - NvrInfo nvrInfo = new NvrInfo(); - nvrInfo.setNvrIp(camera.getIp()); - nvrInfo.setServerPort(camera.getPort()); - nvrInfo.setAccount(camera.getUserName()); - nvrInfo.setPassword(camera.getPassword()); - login_V40(nvrInfo); + } else { + //从redis中获取lUserID(存在时间200) lUserID = (Integer) redisService.redisTemplate.opsForValue().get(camera.getIp() + "_userId"); - } - HCNetSDK.NET_DVR_JPEGPARA dvrJpegpara = new HCNetSDK.NET_DVR_JPEGPARA(); - dvrJpegpara.wPicSize = 3; - dvrJpegpara.wPicQuality = 0; - dvrJpegpara.write(); - // 2. 创建临时存储目录(系统临时目录更安全) - Path tempDir = Paths.get(System.getProperty("java.io.tmpdir"), "hik_capture"); - // 生成唯一文件名(IP+时间戳) - String fileName = String.format("%s_%s.jpg", camera.getIp(), DateUtils.dateTimeNow("yyyyMMddHHmmss")); - Path tempImagePath = tempDir.resolve(fileName); - try { - if (!Files.exists(tempDir)) { - Files.createDirectories(tempDir); + //判断lUserID是否为空 + if (ObjectUtil.isEmpty(lUserID)) { + //重新登录获取lUserID + NvrInfo nvrInfo = new NvrInfo(); + nvrInfo.setNvrIp(camera.getIp()); + nvrInfo.setServerPort(camera.getPort()); + nvrInfo.setAccount(camera.getUserName()); + nvrInfo.setPassword(camera.getPassword()); + login_V40(nvrInfo); + lUserID = (Integer) redisService.redisTemplate.opsForValue().get(camera.getIp() + "_userId"); } - boolean b = hcNetSDK.NET_DVR_CaptureJPEGPicture(lUserID, camera.getChannel(), dvrJpegpara, - tempImagePath.toString().getBytes("GBK")); - if (!b) { -// System.out.println("设置设备进行抓图失败,错误码:" + hcNetSDK.NET_DVR_GetLastError()); - log.error("设置设备进行抓图失败,错误码:" + hcNetSDK.NET_DVR_GetLastError()); + HCNetSDK.NET_DVR_JPEGPARA dvrJpegpara = new HCNetSDK.NET_DVR_JPEGPARA(); + dvrJpegpara.wPicSize = 3; + dvrJpegpara.wPicQuality = 0; + dvrJpegpara.write(); + + // 确保目录存在 + File picDir = new File("D:\\pic"); + if (!picDir.exists()) { + picDir.mkdirs(); // 如果目录不存在,创建它 + } + //添加重试机制 + final int MAX_RETRIES = 5; // 最大重试次数 + boolean success = false; + int retryCount = 0; + while (!success && retryCount < MAX_RETRIES) { + try { + retryCount++; + log.info("第{}次尝试抓图", retryCount); + // 生成文件名(例如:camera_ip + timestamp) + String fileName = "D:\\pic\\" + camera.getIp() + "_" + System.currentTimeMillis() + ".jpg"; + Path tempImagePath = Paths.get(fileName); + boolean b = hcNetSDK.NET_DVR_CaptureJPEGPicture(lUserID, camera.getChannel(), dvrJpegpara, + tempImagePath.toString().getBytes("GBK")); + if (!b) { + log.error("设置设备进行抓图失败,错误码:" + hcNetSDK.NET_DVR_GetLastError()); + log.warn("第{}次抓图超时", retryCount); + } else { + //抓图成功 + InputStream inputStream = Files.newInputStream(tempImagePath); + byte[] bytes = StreamUtils.copyToByteArray(inputStream); + log.error("第{}次抓图成功: {}", retryCount); + return new ByteArrayInputStream(bytes); + } + } catch (Exception e) { + log.error("第{}次抓图失败: {}", retryCount, e.getMessage()); + } } - //图片流 - InputStream inputStream = Files.newInputStream(tempImagePath); - byte[] bytes = StreamUtils.copyToByteArray(inputStream); - // 确保删除临时文件 - Files.deleteIfExists(tempImagePath); - return new ByteArrayInputStream(bytes); - } catch (Exception e) { - log.error("抓图失败" + e.getMessage()); return null; } + } public byte[] loadDefaultImage() throws IOException { @@ -333,3 +377,4 @@ public class IvsCameraServiceImpl implements IvsCameraService { } } } +