Browse Source

refactor: 重构海康实时测温方法,将测温和抓图方法归一管理

master
yinhuaiwei 2 months ago
parent
commit
8c5d685c4d
8 changed files with 386 additions and 268 deletions
  1. +2
    -1
      src/main/java/com/inspect/nvr/controller/InfraredController.java
  2. +1
    -2
      src/main/java/com/inspect/nvr/controller/IvsCameraController.java
  3. +5
    -5
      src/main/java/com/inspect/nvr/service/CommonCameraService.java
  4. +20
    -20
      src/main/java/com/inspect/nvr/service/DahuaCameraService.java
  5. +268
    -0
      src/main/java/com/inspect/nvr/service/HikCameraService.java
  6. +0
    -161
      src/main/java/com/inspect/nvr/service/HikCaptureService.java
  7. +78
    -67
      src/main/java/com/inspect/nvr/service/impl/HikVisionServiceImpl.java
  8. +12
    -12
      src/main/java/com/inspect/nvr/service/impl/IvsCameraServiceImpl.java

+ 2
- 1
src/main/java/com/inspect/nvr/controller/InfraredController.java View File

@ -1,6 +1,7 @@
package com.inspect.nvr.controller;
import com.alibaba.fastjson.JSONObject;
import com.inspect.nvr.aop.TimeTrace;
import com.inspect.nvr.domain.Infrared.*;
import com.inspect.nvr.service.HikVisionService;
import com.inspect.nvr.hikVision.utils.AjaxResult;
@ -11,7 +12,6 @@ import org.springframework.core.io.InputStreamResource;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
@ -53,6 +53,7 @@ public class InfraredController {
// public AjaxResult cameraHongWaiHk(@RequestBody Camera camera) {
// return hikVisionService.cameraHongWaiHk(camera);
// }
@TimeTrace
@PostMapping("/cameraHong")
@ResponseBody
public AjaxResult cameraHong(@RequestBody Camera camera) {


+ 1
- 2
src/main/java/com/inspect/nvr/controller/IvsCameraController.java View File

@ -102,12 +102,11 @@ public class IvsCameraController {
@TimeTrace
@GetMapping("/digest")
public ResponseEntity<String> rtsp(@RequestParam("filesessionid") String fileSessionId) {
public ResponseEntity<String> digest(@RequestParam("filesessionid") String fileSessionId) {
byte[] bytes = ivsCameraService.captureDigest(fileSessionId);
if (bytes == null || bytes.length == 0) {
return ResponseEntity.ok().body("Not OK");
}
return ResponseEntity.ok().body("OK");
}
}

src/main/java/com/inspect/nvr/service/BaseCaptureService.java → src/main/java/com/inspect/nvr/service/CommonCameraService.java View File


src/main/java/com/inspect/nvr/service/DahuaCaptureService.java → src/main/java/com/inspect/nvr/service/DahuaCameraService.java View File


+ 268
- 0
src/main/java/com/inspect/nvr/service/HikCameraService.java View File

@ -0,0 +1,268 @@
package com.inspect.nvr.service;
import com.inspect.nvr.domain.Infrared.NvrInfo;
import com.inspect.nvr.domain.Infrared.TemperatureData;
import com.inspect.nvr.hikVision.utils.jna.HCNetSDK;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StreamUtils;
import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantLock;
/**
* 海康设备SDK服务
* 同一个IP同一个通道串行
* 同一个IP不同通道最多4个线程并发
* 不同IP并发抓图不限制
*/
@Slf4j
@Service
public class HikCameraService extends CommonCameraService {
/**
* Digest认证抓图URL
* http://<host>/ISAPI/Streaming/channels/<channel><subtype>/picture
* subtype: 01-主码流, 02-子码流
*/
private static final String DIGEST_URL_TEMPLATE = "http://%s/ISAPI/Streaming/channels/%d02/picture";
// 实时测温执行结果映射避免并发访问冲突
private static final ConcurrentHashMap<Long, CompletableFuture<TemperatureData>> THERMOMETRY_REQUESTS = new ConcurrentHashMap<>();
// 实时测温请求的唯一ID生成器
private static final AtomicLong THERMOMETRY_SERIAL = new AtomicLong(1);
@Resource
private HikLoginService hikLoginService;
@Resource
private HCNetSDK hcNetSDK;
public <T> T withConcurrencyControl(NvrInfo nvrInfo, int channel, Callable<T> task) {
String ip = nvrInfo.getNvrIp();
Semaphore nvrSemaphore = getOrCreateSemaphore(ip);
ReentrantLock channelLock = getOrCreateLock(ip, channel);
// 1.先获取该NVR的全局并发许可
nvrSemaphore.acquireUninterruptibly();
try {
// 2.再获取该通道的独占锁保证同一通道串行
channelLock.lock();
try {
return task.call();
} catch (Exception e) {
log.error("[海康]任务执行异常:", e);
return null;
} finally {
// 必须先unlock通道锁再释放NVR全局许可
if (channelLock.isHeldByCurrentThread()) {
channelLock.unlock();
}
}
} finally {
// 3.释放NVR全局许可
nvrSemaphore.release();
}
}
/**
* 受并发控制的海康抓图
*/
public byte[] capture(NvrInfo nvrInfo, int channel) {
return withConcurrencyControl(nvrInfo, channel, () -> captureWithRetry(nvrInfo, channel));
}
/**
* Digest认证抓图
*/
public byte[] captureDigest(NvrInfo nvrInfo, int channel) {
return withConcurrencyControl(nvrInfo, channel, () -> captureDigest(nvrInfo, channel, DIGEST_URL_TEMPLATE, getFullPath("hk_digest", nvrInfo.getNvrIp(), channel)));
}
/**
* 受并发控制的海康实时测温
*/
public TemperatureData realTimeThermometry(NvrInfo nvrInfo, int channel) {
return withConcurrencyControl(nvrInfo, channel, () -> getRealTimeThermometry(nvrInfo, channel));
}
private byte[] captureWithRetry(NvrInfo nvrInfo, int channel) {
Path fullPath = getFullPath("hk", nvrInfo.getNvrIp(), channel);
ensureDirectoryExists(fullPath.getParent());
int retryCount = 0;
int maxRetries = DEFAULT_MAX_RETRIES;
while (retryCount < maxRetries) {
try {
// byte[] imageBytes = captureJPEGPicture(nvrInfo, channel, fullPath);
byte[] imageBytes = captureJPEGPictureNew(nvrInfo, channel, fullPath);
if (imageBytes == null) {
int errorCode = hcNetSDK.NET_DVR_GetLastError();
throw new RuntimeException("SDK抓图失败,错误码" + errorCode);
}
log.info("[海康]抓图成功(第{}次):{}", retryCount + 1, fullPath);
return imageBytes;
} catch (Exception e) {
log.error("[海康]抓图异常(第{}次):{}", retryCount + 1, e.getMessage());
try {
Thread.sleep(2000);
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
break;
}
} finally {
retryCount++;
}
}
// 当SDK抓图失败时尝试使用Digest认证抓图
byte[] imageBytes = captureDigest(nvrInfo, channel, DIGEST_URL_TEMPLATE, fullPath);
if (imageBytes == null) {
// 当所有抓图方式均失败时记录失败图片
writeCaptureFailedImage(fullPath);
log.info("[海康]所有抓图方式均失败,图片地址:{}", fullPath);
return new byte[0];
}
log.info("[海康]digest抓图成功,图片地址:{}", fullPath);
return imageBytes;
}
/**
* 大华SDK抓图具体实现旧版
*/
private byte[] captureJPEGPicture(NvrInfo nvrInfo, int channel, Path fullPath) throws Exception {
int userId = hikLoginService.login(nvrInfo);
// 兼容 C/C++ 编写的本地库 C 语言用 \0 标记字符串结束
HCNetSDK.NET_DVR_JPEGPARA jpegpara = new HCNetSDK.NET_DVR_JPEGPARA();
jpegpara.wPicSize = 0xff;
jpegpara.wPicQuality = 1;
jpegpara.write();
byte[] filePathBytes = (fullPath.toString() + "\0").getBytes("GBK");
boolean isCaptured = hcNetSDK.NET_DVR_CaptureJPEGPicture(userId, channel, jpegpara, filePathBytes);
if (isCaptured) {
// 验证文件是否有效
if (!isValidJpeg(fullPath)) {
// 文件乱码修改文件名
log.info("[海康]文件无效,图片地址:{}", fullPath);
String dirName = fullPath.getParent().toString();
String fileName = fullPath.getFileName().toString();
File dir = new File(dirName);
File[] files = dir.listFiles((file, name) -> name.startsWith(fileName));
if (files != null) {
for (File file : files) {
file.renameTo(new File(fullPath.toString()));
}
}
}
// 读取文件并返回字节数组
try (InputStream inputStream = Files.newInputStream(fullPath)) {
return StreamUtils.copyToByteArray(inputStream);
}
}
return null;
}
/**
* 大华SDK抓图具体实现新版
*/
private byte[] captureJPEGPictureNew(NvrInfo nvrInfo, int channel, Path fullPath) throws Exception {
int userId = hikLoginService.login(nvrInfo);
HCNetSDK.NET_DVR_JPEGPARA jpegpara = new HCNetSDK.NET_DVR_JPEGPARA();
jpegpara.wPicSize = 0xff;
jpegpara.wPicQuality = 0;
jpegpara.write();
HCNetSDK.BYTE_ARRAY byteArray = new HCNetSDK.BYTE_ARRAY(10 * 1024 * 1024);
IntByReference ret = new IntByReference(0);
log.info("[海康]开始抓图,UserID={},IP={},Channel={}", userId, nvrInfo.getNvrIp(), channel);
boolean isCaptured = hcNetSDK.NET_DVR_CaptureJPEGPicture_NEW(userId, channel, jpegpara, byteArray.getPointer(), byteArray.size(), ret);
if (isCaptured) {
byteArray.read();
byte[] imageBytes = byteArray.byValue;
// 图片写入本地
try (FileOutputStream fos = new FileOutputStream(fullPath.toString())) {
fos.write(imageBytes, 0, ret.getValue());
}
return imageBytes;
}
return null;
}
/**
* 海康SDK实施测温具体实现异步
* 通过CompletableFuture实现异步回调通知
*/
private TemperatureData getRealTimeThermometry(NvrInfo nvrInfo, int channel) {
int userId = hikLoginService.login(nvrInfo);
HCNetSDK.NET_DVR_REALTIME_THERMOMETRY_COND cond = new HCNetSDK.NET_DVR_REALTIME_THERMOMETRY_COND();
cond.dwSize = cond.size();
cond.dwChan = channel;
cond.byRuleID = 1;//规则ID0代表获取全部规则具体规则ID从1开始
cond.byMode = 1;//长连接模式0-保留1-定时模式2-温差模式
cond.wInterval = 5;//上传间隔仅温差模式支持取值范围1-3600 填0则默认3600S上传一次
cond.write(); // 手动同步结构体到内存
Pointer lpInBuffer = cond.getPointer();
int dwInBufferSize = cond.size();
// 为每个测温请求生成唯一的请求ID
long requestId = THERMOMETRY_SERIAL.getAndIncrement();
Pointer pUserData = Pointer.createConstant(requestId);
CompletableFuture<TemperatureData> future = new CompletableFuture<>();
THERMOMETRY_REQUESTS.put(requestId, future);
final int TIMEOUT_SEC = 5;
// 测温返回的句柄
int lHandle = -1;
try {
log.info("[海康]开始实时测温,UserID={},IP={},Channel={},requestId={}", userId, nvrInfo.getNvrIp(), channel, requestId);
lHandle = hcNetSDK.NET_DVR_StartRemoteConfig(userId, HCNetSDK.NET_DVR_GET_REALTIME_THERMOMETRY, lpInBuffer, dwInBufferSize, new fRemoteConfigCB(), pUserData);
if (lHandle < 0) {
int errorCode = hcNetSDK.NET_DVR_GetLastError();
throw new RuntimeException("SDK测温失败,错误码:" + errorCode);
}
return future.get(TIMEOUT_SEC, TimeUnit.SECONDS);
} catch (TimeoutException e) {
log.error("[海康]测温超时:在 " + TIMEOUT_SEC + " 秒内未收到设备回调");
} catch (Exception e) {
log.error("[海康]测温异常:{}", e.getMessage());
} finally {
THERMOMETRY_REQUESTS.remove(requestId);
hcNetSDK.NET_DVR_StopRemoteConfig(lHandle);
}
return null;
}
/**
* NET_DVR_StartRemoteConfig实时测温回调函数重写
*/
public static class fRemoteConfigCB implements HCNetSDK.FRemoteConfigCallBack {
@Override
public void invoke(int dwType, Pointer lpBuffer, int dwBufLen, Pointer pUserData) {
long requestId = Pointer.nativeValue(pUserData);
CompletableFuture<TemperatureData> future = THERMOMETRY_REQUESTS.remove(requestId);
if (future != null) {
log.info("[海康]匹配到测温回调,类型: {}, 长度:{}", dwType, dwBufLen);
if (dwType == 2) {
HCNetSDK.NET_DVR_THERMOMETRY_UPLOAD thermometryUpload = new HCNetSDK.NET_DVR_THERMOMETRY_UPLOAD();
thermometryUpload.write();
Pointer pmt = thermometryUpload.getPointer();
pmt.write(0, lpBuffer.getByteArray(0, thermometryUpload.size()), 0, thermometryUpload.size());
thermometryUpload.read();
String strTemp = "规则ID:" + thermometryUpload.byRuleID + "规则名称:" + thermometryUpload.szRuleName + "规则类型:" + thermometryUpload.byRuleCalibType + "预置点号:" + thermometryUpload.wPresetNo + "点温度:" + thermometryUpload.struPointThermCfg.fTemperature + "点坐标:" + thermometryUpload.struPointThermCfg.struPoint.fX + "," + thermometryUpload.struPointThermCfg.struPoint.fY + "区域最高温度:" + thermometryUpload.struLinePolygonThermCfg.fMaxTemperature + "区域最低温度:" + thermometryUpload.struLinePolygonThermCfg.fMinTemperature + "区域平均温度:" + thermometryUpload.struLinePolygonThermCfg.fAverageTemperature + "区域温差:" + thermometryUpload.struLinePolygonThermCfg.fTemperatureDiff + "\n";
log.info("[海康]实时测温成功,requestId={}, data={}", requestId, strTemp);
HCNetSDK.NET_DVR_LINEPOLYGON_THERM_CFG struLinePolygonThermCfg = thermometryUpload.struLinePolygonThermCfg;
// 封装所有温度数据
TemperatureData data = new TemperatureData(String.valueOf(struLinePolygonThermCfg.fMaxTemperature), String.valueOf(struLinePolygonThermCfg.fMinTemperature), struLinePolygonThermCfg.fAverageTemperature, struLinePolygonThermCfg.fTemperatureDiff, thermometryUpload.dwChan, thermometryUpload.byRuleID);
future.complete(data);
}
} else {
log.error("[海康]收到未匹配的测温回调, requestId={}", requestId);
}
}
}
}

+ 0
- 161
src/main/java/com/inspect/nvr/service/HikCaptureService.java View File

@ -1,161 +0,0 @@
package com.inspect.nvr.service;
import com.inspect.nvr.domain.Infrared.NvrInfo;
import com.inspect.nvr.hikVision.utils.jna.HCNetSDK;
import com.sun.jna.ptr.IntByReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StreamUtils;
import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.ReentrantLock;
/**
* 海康设备抓图服务
* 同一个IP同一个通道串行抓图
* 同一个IP不同通道最多4个线程并发抓图
* 不同IP并发抓图不限制
*/
@Slf4j
@Service
public class HikCaptureService extends BaseCaptureService {
/**
* Digest认证抓图URL
* http://<host>/ISAPI/Streaming/channels/<channel><subtype>/picture
* subtype: 01-主码流, 02-子码流
*/
private static final String DIGEST_URL_TEMPLATE = "http://%s/ISAPI/Streaming/channels/%d02/picture";
@Resource
private HikLoginService hikLoginService;
@Resource
private HCNetSDK hcNetSDK;
public byte[] capture(NvrInfo nvrInfo, int channel) {
String ip = nvrInfo.getNvrIp();
Semaphore nvrSemaphore = getOrCreateSemaphore(ip);
ReentrantLock channelLock = getOrCreateLock(ip, channel);
// 1.先获取该NVR的全局并发许可
nvrSemaphore.acquireUninterruptibly();
try {
// 2.再获取该通道的独占锁保证同一通道串行
channelLock.lock();
try {
return captureWithRetry(nvrInfo, channel);
} finally {
// 必须先unlock通道锁再释放NVR全局许可
if (channelLock.isHeldByCurrentThread()) {
channelLock.unlock();
}
}
} finally {
// 3.释放NVR全局许可
nvrSemaphore.release();
}
}
private byte[] captureWithRetry(NvrInfo nvrInfo, int channel) {
Path fullPath = getFullPath("hk", nvrInfo.getNvrIp(), channel);
ensureDirectoryExists(fullPath.getParent());
int retryCount = 0;
int maxRetries = DEFAULT_MAX_RETRIES;
while (retryCount < maxRetries) {
try {
// byte[] imageBytes = captureJPEGPicture(nvrInfo, channel, fullPath);
byte[] imageBytes = captureJPEGPictureNew(nvrInfo, channel, fullPath);
if (imageBytes == null) {
int errorCode = hcNetSDK.NET_DVR_GetLastError();
throw new RuntimeException("SDK抓图失败,错误码" + errorCode);
}
log.info("[海康]抓图成功(第{}次):{}", retryCount + 1, fullPath);
return imageBytes;
} catch (Exception e) {
log.error("[海康]抓图异常(第{}次):{}", retryCount + 1, e.getMessage());
try {
Thread.sleep(2000);
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
break;
}
} finally {
retryCount++;
}
}
// 当SDK抓图失败时尝试使用Digest认证抓图
byte[] imageBytes = captureDigest(nvrInfo, channel, DIGEST_URL_TEMPLATE, fullPath);
if (imageBytes == null) {
// 当所有抓图方式均失败时记录失败图片
WriteCaptureFailedImage(fullPath);
log.info("[海康]所有抓图方式均失败,图片地址:{}", fullPath);
return new byte[0];
}
log.info("[海康]digest抓图成功,图片地址:{}", fullPath);
return imageBytes;
}
/**
* 旧版抓图备用
*/
private byte[] captureJPEGPicture(NvrInfo nvrInfo, int channel, Path fullPath) throws Exception {
int userId = hikLoginService.login(nvrInfo);
// 兼容 C/C++ 编写的本地库 C 语言用 \0 标记字符串结束
HCNetSDK.NET_DVR_JPEGPARA jpegpara = new HCNetSDK.NET_DVR_JPEGPARA();
jpegpara.wPicSize = 0xff;
jpegpara.wPicQuality = 1;
jpegpara.write();
byte[] filePathBytes = (fullPath.toString() + "\0").getBytes("GBK");
boolean isCaptured = hcNetSDK.NET_DVR_CaptureJPEGPicture(userId, channel, jpegpara, filePathBytes);
if (isCaptured) {
// 验证文件是否有效
if (!isValidJPEG(fullPath)) {
// 文件乱码修改文件名
log.info("[海康]文件无效,图片地址:{}", fullPath);
String dirName = fullPath.getParent().toString();
String fileName = fullPath.getFileName().toString();
File dir = new File(dirName);
File[] files = dir.listFiles((file, name) -> name.startsWith(fileName));
if (files != null) {
for (File file : files) {
file.renameTo(new File(fullPath.toString()));
}
}
}
// 读取文件并返回字节数组
try (InputStream inputStream = Files.newInputStream(fullPath)) {
return StreamUtils.copyToByteArray(inputStream);
}
}
return null;
}
private byte[] captureJPEGPictureNew(NvrInfo nvrInfo, int channel, Path fullPath) throws Exception {
int userId = hikLoginService.login(nvrInfo);
HCNetSDK.NET_DVR_JPEGPARA jpegpara = new HCNetSDK.NET_DVR_JPEGPARA();
jpegpara.wPicSize = 0xff;
jpegpara.wPicQuality = 0;
jpegpara.write();
HCNetSDK.BYTE_ARRAY byteArray = new HCNetSDK.BYTE_ARRAY(10 * 1024 * 1024);
IntByReference ret = new IntByReference(0);
log.info("[海康]开始抓图,UserID={},IP={}, Channel={}", userId, nvrInfo.getNvrIp(), channel);
boolean isCaptured = hcNetSDK.NET_DVR_CaptureJPEGPicture_NEW(userId, channel, jpegpara, byteArray.getPointer(), byteArray.size(), ret);
if (isCaptured) {
byteArray.read();
byte[] imageBytes = byteArray.byValue;
// 图片写入本地
try (FileOutputStream fos = new FileOutputStream(fullPath.toString())) {
fos.write(imageBytes, 0, ret.getValue());
}
return imageBytes;
}
return null;
}
public byte[] captureDigest(NvrInfo nvrInfo, int channel) {
return captureDigest(nvrInfo, channel, DIGEST_URL_TEMPLATE, getFullPath("hk_digest", nvrInfo.getNvrIp(), channel));
}
}

+ 78
- 67
src/main/java/com/inspect/nvr/service/impl/HikVisionServiceImpl.java View File

@ -17,6 +17,7 @@ import com.inspect.nvr.hikVision.utils.AjaxResult;
import com.inspect.nvr.hikVision.utils.StringUtils;
import com.inspect.nvr.hikVision.utils.jna.HCNetSDK;
import com.inspect.nvr.hikVision.utils.jna.HikVisionUtils;
import com.inspect.nvr.service.HikCameraService;
import com.inspect.nvr.service.HikFRemoteConfigCallBack_imp;
import com.inspect.nvr.service.HikLoginService;
import com.inspect.nvr.service.HikVisionService;
@ -66,14 +67,10 @@ import java.util.concurrent.*;
@Service
public class HikVisionServiceImpl implements HikVisionService {
private static HikFExceptionCallBack_Imp fExceptionCallBack;
private final Logger log = LoggerFactory.getLogger(this.getClass());
@Autowired
private HCNetSDK hcNetSDK;
private static HikFExceptionCallBack_Imp fExceptionCallBack;
private String picPath;
// @Value("${file.hrUavUrl:test}")
@ -112,16 +109,69 @@ public class HikVisionServiceImpl implements HikVisionService {
@Resource
private RedisService redisService;
@Resource
private HikCameraService hikCameraService;
private Integer lUserID;
@Autowired
private HikLoginService hikLoginService;
//二维数组转 CSV
private static String convertMatrixToCsv(float[][] matrix) {
StringBuilder csvBuilder = new StringBuilder();
for (float[] row : matrix) {
for (int i = 0; i < row.length; i++) {
csvBuilder.append(row[i]);
if (i < row.length - 1) {
csvBuilder.append(",");
}
}
csvBuilder.append("\n");
}
return csvBuilder.toString();
}
public static String truncateFileNameToCsv(String originalPath) {
// 获取文件名部分最后一个 '/' 之后的内容
int lastSlashIndex = originalPath.lastIndexOf('/');
if (lastSlashIndex == -1) {
// 如果没有路径分隔符直接处理整个字符串
return processFileNameToCsv(originalPath);
}
// 分离路径和文件名
String path = originalPath.substring(0, lastSlashIndex + 1);
String fileName = originalPath.substring(lastSlashIndex + 1);
// 处理文件名部分并强制改为.csv
String processedFileName = processFileNameToCsv(fileName);
return path + processedFileName;
}
private static String processFileNameToCsv(String fileName) {
// 去掉文件扩展名如果有
int lastDotIndex = fileName.lastIndexOf('.');
if (lastDotIndex != -1) {
fileName = fileName.substring(0, lastDotIndex);
}
// 去掉最后一个 '_' 及其后面的部分
int lastUnderscoreIndex = fileName.lastIndexOf('_');
if (lastUnderscoreIndex != -1) {
fileName = fileName.substring(0, lastUnderscoreIndex);
}
// 强制添加.csv后缀
return fileName + ".csv";
}
@Override
public AjaxResult login(NvrInfo nvrInfo) {
return login_V40(nvrInfo);
}
@Autowired
private HikLoginService hikLoginService;
/**
* 设备登录V40 与V30功能一致
@ -172,9 +222,25 @@ public class HikVisionServiceImpl implements HikVisionService {
}
}
//实时测温接口获取最高温和最低温
/**
* 海康实时测温接口
* 优化并发场景
*/
public TemperatureData StartRemote(Camera camera) {
NvrInfo nvrInfo = new NvrInfo();
nvrInfo.setNvrIp(camera.getIp());
nvrInfo.setServerPort(camera.getPort());
nvrInfo.setAccount(camera.getUserName());
nvrInfo.setPassword(camera.getPassword());
TemperatureData data = hikCameraService.realTimeThermometry(nvrInfo, camera.getChannel());
return data;
}
/**
* @deprecated 实时测温接口获取最高温和最低温
*/
@Deprecated
public TemperatureData StartRemoteOld(Camera camera) {
int result = 0;
TemperatureData temperatureData = null;
@ -316,7 +382,6 @@ public class HikVisionServiceImpl implements HikVisionService {
return AjaxResult.success();
}
//抓图 单独测试 未使用
@Override
public Camera cameraPictrue(Camera camera) throws Exception {
@ -627,27 +692,14 @@ public class HikVisionServiceImpl implements HikVisionService {
return outputPath;
}
//二维数组转 CSV
private static String convertMatrixToCsv(float[][] matrix) {
StringBuilder csvBuilder = new StringBuilder();
for (float[] row : matrix) {
for (int i = 0; i < row.length; i++) {
csvBuilder.append(row[i]);
if (i < row.length - 1) {
csvBuilder.append(",");
}
}
csvBuilder.append("\n");
}
return csvBuilder.toString();
}
@Override
public AjaxResult capturePicture(InfraPictureInfo infraPictureInfo) {
return AjaxResult.success("设置成功");
}
//从ftp获取csv流转换成二维数组
//框选温度值计算
public InfraredInfo matrixTemperatureShow(Coordinate coordinate, short width, short height, float[][] temperatureMatrix) {
InfraredInfo infraredInfo = new InfraredInfo();
@ -781,8 +833,6 @@ public class HikVisionServiceImpl implements HikVisionService {
}
//从ftp获取csv流转换成二维数组
private float[][] parseCsvFromFtp2(String csvUrl) throws IOException, URISyntaxException {
log.info("连接ftp,获取csv文件");
InputStream inputStream = null;
@ -896,7 +946,6 @@ public class HikVisionServiceImpl implements HikVisionService {
return inputStream;
}
@Override
public ResponseEntity<String> irPicAnalyse(final String analyseRequestJson) {
log.info("[INFRARED] irPicAnalyse: analyseRequestJson={}", analyseRequestJson);
@ -981,7 +1030,6 @@ public class HikVisionServiceImpl implements HikVisionService {
return infraredInfo;
}
@Override
public InputStream downloadCsv(String filePath) {
log.info("解析csv图片地址" + filePath);
@ -1034,43 +1082,6 @@ public class HikVisionServiceImpl implements HikVisionService {
return inputStream;
}
public static String truncateFileNameToCsv(String originalPath) {
// 获取文件名部分最后一个 '/' 之后的内容
int lastSlashIndex = originalPath.lastIndexOf('/');
if (lastSlashIndex == -1) {
// 如果没有路径分隔符直接处理整个字符串
return processFileNameToCsv(originalPath);
}
// 分离路径和文件名
String path = originalPath.substring(0, lastSlashIndex + 1);
String fileName = originalPath.substring(lastSlashIndex + 1);
// 处理文件名部分并强制改为.csv
String processedFileName = processFileNameToCsv(fileName);
return path + processedFileName;
}
private static String processFileNameToCsv(String fileName) {
// 去掉文件扩展名如果有
int lastDotIndex = fileName.lastIndexOf('.');
if (lastDotIndex != -1) {
fileName = fileName.substring(0, lastDotIndex);
}
// 去掉最后一个 '_' 及其后面的部分
int lastUnderscoreIndex = fileName.lastIndexOf('_');
if (lastUnderscoreIndex != -1) {
fileName = fileName.substring(0, lastUnderscoreIndex);
}
// 强制添加.csv后缀
return fileName + ".csv";
}
// NVR跳转到预置位
public AjaxResult NvrCameraAngleJump(Camera camera) {


+ 12
- 12
src/main/java/com/inspect/nvr/service/impl/IvsCameraServiceImpl.java View File

@ -55,9 +55,9 @@ public class IvsCameraServiceImpl implements IvsCameraService {
@Autowired
private CameraController cameraController;
@Autowired
private HikCaptureService hikCaptureService;
private HikCameraService hikCameraService;
@Autowired
private DahuaCaptureService dhCaptureService;
private DahuaCameraService dahuaCameraService;
@Autowired
private HikLoginService hikLoginService;
@ -119,7 +119,7 @@ public class IvsCameraServiceImpl implements IvsCameraService {
cameraHw.setPassword(splitArray[11]);
//获取红外温度
TemperatureData temper = retry(cameraHw, camera, cameraType);
if(retryMode == 1 && StringUtils.isNull(temper)){
if (retryMode == 1 && StringUtils.isNull(temper)) {
ptzControlResult = PtzControlResult.builder()
.resultCode("-1")
.build();
@ -397,12 +397,12 @@ public class IvsCameraServiceImpl implements IvsCameraService {
nvrInfo.setPassword(camera.getPassword());
if (ObjectUtil.equals(camera.getCameraType(), 1)) {
log.info("大华相机拍照");
byte[] bytes = dhCaptureService.capture(nvrInfo, camera.getChannel());
log.info("大华相机抓图");
byte[] bytes = dahuaCameraService.capture(nvrInfo, camera.getChannel());
return new ByteArrayInputStream(bytes);
} else {
log.info("海康相机拍照");
byte[] bytes = hikCaptureService.capture(nvrInfo, camera.getChannel());
log.info("海康相机抓图");
byte[] bytes = hikCameraService.capture(nvrInfo, camera.getChannel());
return new ByteArrayInputStream(bytes);
}
}
@ -412,7 +412,7 @@ public class IvsCameraServiceImpl implements IvsCameraService {
final String rawString = StringHexConverter.fromHex(fileSessionId);
log.info("downloadImage hexString: {}, rawString: {}", fileSessionId, rawString);
String[] cameraAddressInfos = rawString.split((":"));
log.info("doCapture ip: {}, port: {}, channel: {}, pointName: {},cameraType: {}, username: {}, password: {}", cameraAddressInfos[0], cameraAddressInfos[1], cameraAddressInfos[2], cameraAddressInfos[3], cameraAddressInfos[4], cameraAddressInfos[5], cameraAddressInfos[6]);
log.info("captureDigest ip: {}, port: {}, channel: {}, pointName: {},cameraType: {}, username: {}, password: {}", cameraAddressInfos[0], cameraAddressInfos[1], cameraAddressInfos[2], cameraAddressInfos[3], cameraAddressInfos[4], cameraAddressInfos[5], cameraAddressInfos[6]);
Camera camera = new Camera();
camera.setIp(cameraAddressInfos[0]);
camera.setPort(Integer.parseInt(cameraAddressInfos[1]));
@ -429,12 +429,12 @@ public class IvsCameraServiceImpl implements IvsCameraService {
nvrInfo.setPassword(camera.getPassword());
if (ObjectUtil.equals(camera.getCameraType(), 1)) {
log.info("大华相机拍照");
byte[] bytes = dhCaptureService.captureDigest(nvrInfo, camera.getChannel());
log.info("大华相机Digest抓图");
byte[] bytes = dahuaCameraService.captureDigest(nvrInfo, camera.getChannel());
return bytes;
} else {
log.info("海康相机拍照");
byte[] bytes = hikCaptureService.captureDigest(nvrInfo, camera.getChannel());
log.info("海康相机Digest抓图");
byte[] bytes = hikCameraService.captureDigest(nvrInfo, camera.getChannel());
return bytes;
}
}


Loading…
Cancel
Save