ard-work/src/main/java/com/ruoyi/alarm/global/service/impl/QueueHandler.java
@@ -138,21 +138,11 @@ } if (guideRes) { log.debug("引导成功"); //region 通知前端 Map<String, Object> message = new HashMap<>(); Map<String, String> data = new HashMap<>(); data.put("cameraId", cmd.getCameraId()); data.put("chanNo", cmd.getChanNo().toString()); data.put("alarmType", cmd.getOperator()); data.put("alarmId", guideTask.getAlarmId()); data.put("wellId", guideTask.getWellId()); message.put("70000", data); WebSocketUtils.sendMessageAll(message); //endregion cameraSdkService.controlLock(cmd);//上锁 cameraSdkService.recordStart(cmd);//开始录像 recordFlag = true; Instant startTime = Instant.now(); Instant startTime1 = startTime; while (recordFlag) { //判断时间 Instant currentTime = Instant.now(); @@ -172,6 +162,19 @@ recordFlag = false;//录像停止 } } //region 通知前端 long seconds = Duration.between(startTime1, currentTime).getSeconds(); // 判断当前时间与上次发送数据的时间间隔是否超过2秒 if (seconds == 2) { Map<String, Object> message = new HashMap<>(); Map<String, String> data = new HashMap<>(); data.put("cameraId", cmd.getCameraId()); data.put("wellId", guideTask.getWellId()); message.put("70000", data); WebSocketUtils.sendMessageAll(message); startTime1 = currentTime; // 更新上次发送数据的时间戳 } //endregion } if (StringUtils.isNotEmpty(url)) { switch (guideTask.getAlarmType()) { ard-work/src/main/java/com/ruoyi/device/camera/controller/CameraSdkController.java
@@ -23,6 +23,10 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -333,6 +337,20 @@ return toAjaxString(path, "相机抓图"); } @ApiOperation("本地抓图") @PostMapping("/localCapture") @Log(title = "相机抓图", businessType = BusinessType.CONTROL) @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"}) public @ResponseBody void localCapture(@RequestBody CameraCmd cmd, HttpServletResponse response) throws IOException { cmd.setOperator(SecurityUtils.getUserId()); response.setContentType("image/jpeg"); AjaxResult result = cameraSdkService.localCapture(cmd); OutputStream outputStream = response.getOutputStream(); byte[] data = (byte[]) result.get("data"); outputStream.write(data); } @ApiOperation("获取相机架设参数") @PostMapping("/getGisInfo") @Log(title = "获取相机架设参数", businessType = BusinessType.CONTROL) @@ -343,10 +361,10 @@ return cameraSdkService.getGisInfo(cmd); } @ApiOperation("录像") //@ApiOperation("录像") @PostMapping("/record") @Log(title = "手动录像开始", businessType = BusinessType.CONTROL) @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.enable"}) //@ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo", "cmd.enable"}) public @ResponseBody AjaxResult record(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); @@ -354,10 +372,10 @@ return AjaxResult.success(url); } @ApiOperation("手动录像开始") //@ApiOperation("手动录像开始") @PostMapping("/recordStart") @Log(title = "手动录像开始", businessType = BusinessType.CONTROL) @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"}) //@ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"}) public @ResponseBody AjaxResult recordStart(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); @@ -365,14 +383,38 @@ return toAjax(b); } @ApiOperation("手动录像停止") //@ApiOperation("手动录像停止") @PostMapping("/recordStop") @Log(title = "手动录像停止", businessType = BusinessType.CONTROL) @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.recordBucketName", "cmd.recordObjectName"}) //@ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.recordBucketName", "cmd.recordObjectName"}) public @ResponseBody AjaxResult recordStop(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); String url = cameraSdkService.recordStopToMinio(cmd); return AjaxResult.success(url); } @ApiOperation("本地录像开始") @PostMapping("/localRecordStart") @Log(title = "本地录像开始", businessType = BusinessType.CONTROL) @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"}) public @ResponseBody AjaxResult localRecordStart(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); return cameraSdkService.localRecordStart(cmd); } @ApiOperation("本地录像停止") @PostMapping("/localRecordStop") @Log(title = "本地录像停止", businessType = BusinessType.CONTROL) @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.chanNo"}) public @ResponseBody void localRecordStop(@RequestBody CameraCmd cmd, HttpServletResponse response) throws IOException { cmd.setOperator(SecurityUtils.getUserId()); response.setContentType("video/mp4"); AjaxResult result = cameraSdkService.localRecordStop(cmd); byte[] recordBytes = (byte[]) result.get("data"); OutputStream outputStream = response.getOutputStream(); outputStream.write(recordBytes); } } ard-work/src/main/java/com/ruoyi/device/camera/factory/CameraSDK.java
@@ -4,6 +4,8 @@ import com.ruoyi.device.camera.domain.ArdCameras; import com.ruoyi.device.camera.domain.CameraCmd; import com.ruoyi.device.channel.domain.ArdChannel; import javax.servlet.http.HttpServletResponse; import java.util.List; import java.util.Map; @@ -65,8 +67,8 @@ //获取云台锁定信息 AjaxResult getPTZLockInfo(CameraCmd cmd); //抓图-返给前端二进制流 AjaxResult captureJPEGPicture(CameraCmd cmd); //本地抓图 AjaxResult localCapture(CameraCmd cmd); //抓图 String picCutCate(CameraCmd cmd); @@ -108,4 +110,9 @@ //获取GIS信息数据 AjaxResult getGisInfo(CameraCmd cmd); //本地录像开始 AjaxResult localRecordStart(CameraCmd cmd); //本地录像停止 AjaxResult localRecordStop(CameraCmd cmd); } ard-work/src/main/java/com/ruoyi/device/camera/service/ICameraSdkService.java
@@ -5,6 +5,7 @@ import com.ruoyi.device.camera.domain.CameraCmd; import org.springframework.scheduling.annotation.Async; import javax.servlet.http.HttpServletResponse; import java.util.Map; public interface ICameraSdkService { @@ -66,8 +67,8 @@ //获取云台锁定信息 AjaxResult getPTZLockInfo(CameraCmd cmd); //抓图-返给前端二进制流 String captureJPEGPicture(CameraCmd cmd); //本地抓图 AjaxResult localCapture(CameraCmd cmd); //抓图 String picCutCate(CameraCmd cmd); @@ -104,4 +105,9 @@ //获取GIS信息数据 AjaxResult getGisInfo(CameraCmd cmd); //本地录像开始 AjaxResult localRecordStart(CameraCmd cmd); //本地录像停止 AjaxResult localRecordStop(CameraCmd cmd); } ard-work/src/main/java/com/ruoyi/device/camera/service/impl/CameraSdkServiceImpl.java
@@ -29,6 +29,7 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.util.*; @@ -384,9 +385,25 @@ } } //本地抓图 @Override public String captureJPEGPicture(CameraCmd cmd) { return null; public AjaxResult localCapture(CameraCmd cmd) { try { String cameraId = cmd.getCameraId(); ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId); if (ardCamera != null) { String factory = ardCamera.getFactory(); CameraSDK cameraSDK = cameraSDKFactory.createCameraSDK(factory); return cameraSDK.localCapture(cmd); } else { return AjaxResult.error("摄像头不存在"); } } catch (Exception ex) { log.error("手动抓图异常:" + ex.getMessage()); return AjaxResult.error("手动抓图异常:" + ex.getMessage()); } } //抓图 @@ -829,4 +846,43 @@ return AjaxResult.error("获取相机架设参数异常:" + ex.getMessage()); } } //本地录像开始 @Override public AjaxResult localRecordStart(CameraCmd cmd) { try { String cameraId = cmd.getCameraId(); ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId); if (ardCamera != null) { String factory = ardCamera.getFactory(); CameraSDK cameraSDK = cameraSDKFactory.createCameraSDK(factory); return cameraSDK.localRecordStart(cmd); } else { return AjaxResult.error("相机不存在"); } } catch (Exception ex) { log.error("本地录像开始异常:" + ex.getMessage()); return AjaxResult.error("本地录像开始异常:" + ex.getMessage()); } } //本地录像停止 @Override public AjaxResult localRecordStop(CameraCmd cmd) { try { String cameraId = cmd.getCameraId(); ArdCameras ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId); if (ardCamera != null) { String factory = ardCamera.getFactory(); CameraSDK cameraSDK = cameraSDKFactory.createCameraSDK(factory); return cameraSDK.localRecordStop(cmd); } else { return AjaxResult.error("相机不存在"); } } catch (Exception ex) { log.error("本地录像停止异常:" + ex.getMessage()); return AjaxResult.error("本地录像停止异常:" + ex.getMessage()); } } } ard-work/src/main/java/com/ruoyi/inspect/service/impl/ArdVideoInspectTaskServiceImpl.java
@@ -14,6 +14,7 @@ import com.ruoyi.inspect.domain.ArdVideoInspectRecord; import com.ruoyi.inspect.mapper.ArdVideoInspectRecordMapper; import com.ruoyi.inspect.mapper.ArdVideoInspectTaskStepMapper; import com.ruoyi.utils.websocket.util.WebSocketUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import com.ruoyi.common.utils.StringUtils; @@ -517,6 +518,14 @@ ardVideoInspectTaskMapper.updateArdVideoInspectTaskWithCurrentSetpInfo(ardVideoInspectTask); } else { log.debug("引导成功!"); //region 通知前端 Map<String, Object> message = new HashMap<>(); Map<String, String> data = new HashMap<>(); data.put("cameraId", cmd.getCameraId()); data.put("wellId", well.getWellId()); message.put("70000", data); WebSocketUtils.sendMessageAll(message); //endregion } } } ard-work/src/main/java/com/ruoyi/sy/service/impl/ArdSyCarServiceImpl.java
@@ -1317,62 +1317,68 @@ */ @Override public List<Map<String, Object>> getNearCar(SchedulingParam param) { Double longitude = param.getLongitude(); Double latitude = param.getLatitude(); Integer radius = param.getSealingRadius(); if (longitude == null && latitude == null) { log.debug("原点坐标为空"); return null; } if (radius == null) { log.debug("半径距离为空"); return null; } String userId = SecurityUtils.getUserId(); ArdSyUser syUser = new ArdSyUser(); syUser.setSysUserId(userId); List<ArdSyUser> ardSyUserList = ardSyUserMapper.selectArdSyUserList(syUser); if (ardSyUserList.size() == 0) { log.debug("用户未挂接三一车辆"); return null; } ArdSyUser ardSyUser = ardSyUserList.get(0); String syUrl = redisCache.getCacheObject("sys_config:syCarPT"); String passwordMd5 = DigestUtils.md5Hex(ardSyUser.getPassword()); Map<String, Object> LogInResult = sYClient.logIn(syUrl, passwordMd5, ardSyUser.getUserId()); String sessionId = (String) LogInResult.get("sessionId"); try { Double longitude = param.getLongitude(); Double latitude = param.getLatitude(); Integer radius = param.getSealingRadius(); if (longitude == null && latitude == null) { log.debug("原点坐标为空"); return null; } if (radius == null) { log.debug("半径距离为空"); return null; } String userId = SecurityUtils.getUserId(); ArdSyUser syUser = new ArdSyUser(); syUser.setSysUserId(userId); List<ArdSyUser> ardSyUserList = ardSyUserMapper.selectArdSyUserList(syUser); if (ardSyUserList.size() == 0) { log.debug("用户未挂接三一车辆"); return null; } ArdSyUser ardSyUser = ardSyUserList.get(0); String syUrl = redisCache.getCacheObject("sys_config:syCarPT"); String passwordMd5 = DigestUtils.md5Hex(ardSyUser.getPassword()); Map<String, Object> LogInResult = sYClient.logIn(syUrl, passwordMd5, ardSyUser.getUserId()); String sessionId = (String) LogInResult.get("sessionId"); Map<String, Object> teamList = sYClient.getTeamList(syUrl, ardSyUser.getUserId(), sessionId); List<Map<String, Object>> listMap = (List<Map<String, Object>>) teamList.get("list"); List<Map<String, Object>> allList = new ArrayList<>(); for (Map<String, Object> team : listMap) { String teamId = (String) team.get("teamId"); Map<String, Object> carListMap = sYClient.getCarList1(syUrl, teamId, ardSyUser.getUserId(), sessionId); if (((String) carListMap.get("rspCode")).equals("1")) { List<Map<String, Object>> list = (List<Map<String, Object>>) carListMap.get("list"); allList.addAll(list); Map<String, Object> teamList = sYClient.getTeamList(syUrl, ardSyUser.getUserId(), sessionId); List<Map<String, Object>> listMap = (List<Map<String, Object>>) teamList.get("list"); List<Map<String, Object>> allList = new ArrayList<>(); for (Map<String, Object> team : listMap) { String teamId = (String) team.get("teamId"); Map<String, Object> carListMap = sYClient.getCarList1(syUrl, teamId, ardSyUser.getUserId(), sessionId); if (((String) carListMap.get("rspCode")).equals("1")) { List<Map<String, Object>> list = (List<Map<String, Object>>) carListMap.get("list"); allList.addAll(list); } } } //过滤在线车辆 List<Map<String, Object>> onlineList = allList.stream() .filter(map -> !"离线".equals(map.get("stateCn"))) .collect(Collectors.toList()); List<Map<String, Object>> filteredList = new ArrayList<>(); //过滤半径 for (Map<String, Object> carMap : onlineList) { String carId = (String) carMap.get("carId"); Map<String, Object> carGPSTrack = sYClient.getCarNearPositionByCarId(syUrl, carId, ardSyUser.getUserId(), sessionId); List<Map<String, Object>> carGPSMap = (List<Map<String, Object>>) carGPSTrack.get("list"); Double lng = Double.valueOf((String) carGPSMap.get(0).get("lng")); Double lat = Double.valueOf((String) carGPSMap.get(0).get("lat")); double distance = GisUtil.getDistance( new double[]{longitude,latitude}, new double[]{lng, lat}); if (distance <= radius) { carMap.put("longitude",lng); carMap.put("latitude",lat); filteredList.add(carMap); // 将满足条件的车辆添加到筛选列表中 //过滤在线车辆 List<Map<String, Object>> onlineList = allList.stream() .filter(map -> !"离线".equals(map.get("stateCn"))) .collect(Collectors.toList()); List<Map<String, Object>> filteredList = new ArrayList<>(); //过滤半径 for (Map<String, Object> carMap : onlineList) { String carId = (String) carMap.get("carId"); Map<String, Object> carGPSTrack = sYClient.getCarNearPositionByCarId(syUrl, carId, ardSyUser.getUserId(), sessionId); List<Map<String, Object>> carGPSMap = (List<Map<String, Object>>) carGPSTrack.get("list"); Double lng = Double.valueOf((String) carGPSMap.get(0).get("lng")); Double lat = Double.valueOf((String) carGPSMap.get(0).get("lat")); double distance = GisUtil.getDistance(new double[]{longitude, latitude}, new double[]{lng, lat}); if (distance <= radius) { carMap.put("longitude", lng); carMap.put("latitude", lat); filteredList.add(carMap); // 将满足条件的车辆添加到筛选列表中 } } return filteredList; }catch (Exception e) { log.error("获取附近范围内的车辆信息异常:"+e.getMessage()); return null; } return filteredList; } /** * 获取范围内的车辆信息(多边形) ard-work/src/main/java/com/ruoyi/utils/qymqtt/oldM/PushCallback.java
@@ -39,7 +39,7 @@ @Override public void connectionLost(Throwable throwable) { if (client == null || !client.isConnected()) { System.out.println("连接断开,正在重连...."); //log.error("连接断开,正在重连...."); } } ard-work/src/main/java/com/ruoyi/utils/sdk/common/SdkErrorCodeEnum.java
@@ -15,7 +15,8 @@ NET_DVR_NETWORK_FAIL_CONNECT(7, "连接设备失败。设备不在线或网络原因引起的连接超时等"), NET_DVR_NETWORK_RECV_TIMEOUT(10, "从设备接收数据超时"), NET_DVR_NETWORK_ERRORDATA(11, "传送的数据有误。发送给设备或者从设备接收到的数据错误,如远程参数配置时输入设备不支持的值"), NET_DVR_DVROPRATEFAILED(29, "设备操作失败"); NET_DVR_DVROPRATEFAILED(29, "设备操作失败"), NET_DVR_USERNOTEXIST(47, "用户不存在。注册的用户ID已注销或不可用"); /** * 枚举码 */ ard-work/src/main/java/com/ruoyi/utils/sdk/dhsdk/module/LoginModule.java
@@ -19,7 +19,7 @@ public static NetSDKLib netsdk = NetSDKLib.NETSDK_INSTANCE; // 设备信息 // public static NetSDKLib.NET_DEVICEINFO_Ex m_stDeviceInfo = new NetSDKLib.NET_DEVICEINFO_Ex(); // public static NetSDKLib.NET_DEVICEINFO_Ex m_stDeviceInfo = new NetSDKLib.NET_DEVICEINFO_Ex(); // 登陆句柄 public static LLong m_hLoginHandle = new LLong(0);// ard-work/src/main/java/com/ruoyi/utils/sdk/dhsdk/module/RealPlayModule.java
@@ -13,6 +13,8 @@ */ @Slf4j(topic = "dhSdk") public class RealPlayModule { public static NetSDKLib netsdk = NetSDKLib.NETSDK_INSTANCE; public static NetSDKLib configsdk = NetSDKLib.CONFIG_INSTANCE; /** * \if ENGLISH_LANG * Start RealPlay @@ -101,4 +103,4 @@ } } } } } ard-work/src/main/java/com/ruoyi/utils/sdk/dhsdk/service/impl/DahuaSDK.java
@@ -23,12 +23,14 @@ import com.ruoyi.utils.sdk.common.SdkErrorCodeEnum; import com.ruoyi.utils.sdk.dhsdk.common.ErrorCode; import com.ruoyi.utils.sdk.dhsdk.lib.NetSDKLib; import com.ruoyi.utils.sdk.dhsdk.lib.ToolKits; import com.ruoyi.utils.sdk.dhsdk.lib.enumeration.EM_NEW_CONFIG; import com.ruoyi.utils.sdk.dhsdk.lib.enumeration.NET_EM_CFG_OPERATE_TYPE; import com.ruoyi.utils.sdk.dhsdk.lib.structure.CFG_INFRARED_INFO; import com.ruoyi.utils.sdk.dhsdk.lib.structure.CFG_VIDEO_IN_FOCUS; import com.ruoyi.utils.sdk.dhsdk.lib.structure.DH_OUT_PTZ_VIEW_RANGE_STATUS; import com.ruoyi.utils.sdk.dhsdk.module.*; import com.sun.jna.Native; import com.sun.jna.Pointer; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -36,12 +38,14 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.nio.ByteBuffer; import java.nio.file.Files; import java.nio.file.Paths; import java.text.DecimalFormat; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.*; import java.util.concurrent.PriorityBlockingQueue; import static com.ruoyi.utils.sdk.dhsdk.lib.NetSDKLib.*; @@ -550,6 +554,101 @@ } @Override public AjaxResult localCapture(CameraCmd cmd) { try { String cameraId = cmd.getCameraId(); Integer chanNo = cmd.getChanNo(); if (!GlobalVariable.loginMap.containsKey(cameraId)) { return AjaxResult.error("设备未登录"); } LLong loginId = (LLong) GlobalVariable.loginMap.get(cameraId); String imagePath = FileUtils.createFile("D:/LocalCaptureTemp/" + cameraId + ".jpeg"); fCaptureReceiveCB1 m_CaptureReceiveCB = new fCaptureReceiveCB1(imagePath); CapturePictureModule.setSnapRevCallBack(m_CaptureReceiveCB); boolean b = CapturePictureModule.remoteCapturePicture(loginId, chanNo - 1); if (b) { Thread.sleep(200); byte[] imageBytes = Files.readAllBytes(Paths.get(imagePath)); //OutputStream outputStream = response.getOutputStream(); //outputStream.write(imageBytes); // 创建ByteBuffer并将字节数组写入其中 //ByteBuffer jpegBuffer = ByteBuffer.wrap(imageBytes); //Base64.Encoder decoder = Base64.getEncoder(); //String png_base64 = decoder.encodeToString(jpegBuffer.array());//转换成base64串 return AjaxResult.success(imageBytes); } else { return AjaxResult.error("本地抓图失败"); } } catch (Exception ex) { return AjaxResult.error("本地抓图异常:" + ex); } } //本地录像开始 @Override public AjaxResult localRecordStart(CameraCmd cmd) { try { String cameraId = cmd.getCameraId(); Integer chanNo = cmd.getChanNo(); String path = FileUtils.createFile("D:/LocalRecordTemp/" + cameraId + ".mp4"); if (!GlobalVariable.loginMap.containsKey(cameraId)) { return AjaxResult.error("设备未登录"); } LLong loginId = (LLong) GlobalVariable.loginMap.get(cameraId); LLong lRealHandle; if (GlobalVariable.previewMap.containsKey(cameraId)) { lRealHandle = new LLong(GlobalVariable.previewMap.get(cameraId)); RealPlayModule.stopRealPlay(lRealHandle); GlobalVariable.previewMap.remove(cameraId); log.debug("停止当前录像"); } lRealHandle = RealPlayModule.startRealPlay(loginId, chanNo - 1, path); if (lRealHandle.longValue() <= 0) { log.error("取流失败" + getErrorCodePrint()); } log.debug("本地录像开始取流成功"); GlobalVariable.previewMap.put(cameraId, lRealHandle.intValue()); GlobalVariable.threadMap.put(cameraId, Thread.currentThread().getName()); //if (!netsdk.CLIENT_SaveRealData(lRealHandle, path)) { // log.error("保存视频文件到临时文件夹失败 错误码为: " +getErrorCodePrint()); // return false; //} log.debug("本地录像开始"); return AjaxResult.success("本地录像开始,录像ID:"+lRealHandle); } catch (Exception ex) { log.error("本地录像开始异常" + ex.getMessage()); return AjaxResult.error("本地录像开始异常" + ex.getMessage()); } } //本地录像停止 @Override public AjaxResult localRecordStop(CameraCmd cmd) { try { String cameraId = cmd.getCameraId(); if (!GlobalVariable.loginMap.containsKey(cameraId)) { return AjaxResult.error("设备未登录"); } LLong lRealHandle; if (GlobalVariable.previewMap.containsKey(cameraId)) { lRealHandle = new LLong(GlobalVariable.previewMap.get(cameraId)); RealPlayModule.stopRealPlay(lRealHandle); GlobalVariable.previewMap.remove(cameraId); log.debug("本地录像停止"); String recordPath = FileUtils.createFile("D:/LocalRecordTemp/" + cameraId + ".mp4"); byte[] imageBytes = Files.readAllBytes(Paths.get(recordPath)); // OutputStream outputStream = response.getOutputStream(); // outputStream.write(imageBytes); return AjaxResult.success(imageBytes); } else { return AjaxResult.error("设备未开始录像"); } } catch (Exception ex) { log.error("本地录像停止异常" + ex.getMessage()); return AjaxResult.error("本地录像停止异常" + ex.getMessage()); } } /** * @描述 短时录像 @@ -739,7 +838,6 @@ } LLong loginId = (LLong) GlobalVariable.loginMap.get(cameraId); try { boolean bool = netsdk.CLIENT_DHPTZControlEx(loginId, chanNo - 1, NET_PTZ_POINT_MOVE_CONTROL, 0, PresetIndex, 0, 0); if (!bool) { log.error("转至预置点失败:" + getErrorCodePrint()); @@ -875,10 +973,6 @@ return AjaxResult.success("该功能未实现"); } @Override public AjaxResult captureJPEGPicture(CameraCmd cmd) { return AjaxResult.success("该功能未实现"); } //切换透雾 @Override @@ -1125,4 +1219,31 @@ } } // 抓图接收回调:当抓图成功,sdk会调用该函数 public static class fCaptureReceiveCB1 implements NetSDKLib.fSnapRev { private String picPath; public fCaptureReceiveCB1(String picPath) { this.picPath = picPath; } public void invoke(LLong lLoginID, Pointer pBuf, int RevLen, int EncodeType, int CmdSerial, Pointer dwUser) { if (pBuf != null && RevLen > 0) { byte[] buf = pBuf.getByteArray(0, RevLen); //存储到本地 InputStream input = new ByteArrayInputStream(buf); OutputStream output = null; try { output = new FileOutputStream(picPath); byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = input.read(buffer)) != -1) { output.write(buffer, 0, bytesRead); } input.close(); output.close(); } catch (Exception e) { e.printStackTrace(); } } } } } ard-work/src/main/java/com/ruoyi/utils/sdk/hiksdk/controller/HikSdkController.java
@@ -17,6 +17,7 @@ import org.springframework.web.bind.annotation.*; import springfox.documentation.annotations.ApiIgnore; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.util.List; import java.util.Map; @@ -259,11 +260,11 @@ return sdk.controlCameraDeicing(cmd); } @PostMapping("/captureJPEGPicture") @PostMapping("/localCapture") public @ResponseBody AjaxResult captureJPEGPicture(@RequestBody CameraCmd cmd) { void localCapture(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); return sdk.captureJPEGPicture(cmd); sdk.localCapture(cmd); } @ApiOperation("相机抓图") ard-work/src/main/java/com/ruoyi/utils/sdk/hiksdk/service/impl/HikvisionSDK.java
@@ -32,9 +32,12 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.math.BigDecimal; import java.nio.ByteBuffer; import java.nio.file.Files; import java.nio.file.Paths; import java.text.DecimalFormat; import java.util.*; import java.util.concurrent.PriorityBlockingQueue; @@ -1497,38 +1500,45 @@ * * @param cmd 相机命令 */ public AjaxResult captureJPEGPicture(CameraCmd cmd) { String cameraId = cmd.getCameraId(); Integer channelNum = cmd.getChanNo(); if (!GlobalVariable.loginMap.containsKey(cameraId)) { return AjaxResult.error("设备未登录"); @Override public AjaxResult localCapture(CameraCmd cmd) { try { String cameraId = cmd.getCameraId(); Integer channelNum = cmd.getChanNo(); if (!GlobalVariable.loginMap.containsKey(cameraId)) { return AjaxResult.error("设备未登录"); } Integer userId = (Integer) GlobalVariable.loginMap.get(cameraId); NET_DVR_WORKSTATE_V30 devwork = new NET_DVR_WORKSTATE_V30(); if (!hCNetSDK.NET_DVR_GetDVRWorkState_V30(userId, devwork)) { int code = hCNetSDK.NET_DVR_GetLastError(); log.error("获取设备工作状态失败: errorCode" + code + " errorInfo" + SdkErrorCodeEnum.getDescByCode(code)); return AjaxResult.error("获取设备工作状态失败: errorCode" + code + " errorInfo" + SdkErrorCodeEnum.getDescByCode(code)); } //图片质量 NET_DVR_JPEGPARA jpeg = new NET_DVR_JPEGPARA(); //设置图片分辨率 jpeg.wPicSize = 0; //设置图片质量 jpeg.wPicQuality = 0; IntByReference a = new IntByReference(); //设置图片大小 ByteBuffer jpegBuffer = ByteBuffer.allocate(1024 * 1024); // 抓图到内存,单帧数据捕获并保存成JPEG存放在指定的内存空间中 boolean is = hCNetSDK.NET_DVR_CaptureJPEGPicture_NEW(userId, channelNum, jpeg, jpegBuffer, 1024 * 1024, a); //log.debug("-----------这里开始图片存入内存----------" + is); // OutputStream outputStream = response.getOutputStream(); //outputStream.write(jpegBuffer.array()); //Base64.Encoder decoder = Base64.getEncoder(); // BASE64Encoder encoder = new BASE64Encoder(); //String png_base64 = decoder.encodeToString(jpegBuffer.array());//转换成base64串 // png_base64 = png_base64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n //log.debug("-----------处理完成截图数据----------"); return AjaxResult.success(jpegBuffer.array()); } catch (Exception ex) { log.error("-----------截图失败----------"); return AjaxResult.error(ex.getMessage()); } Integer userId = (Integer) GlobalVariable.loginMap.get(cameraId); NET_DVR_WORKSTATE_V30 devwork = new NET_DVR_WORKSTATE_V30(); if (!hCNetSDK.NET_DVR_GetDVRWorkState_V30(userId, devwork)) { int code = hCNetSDK.NET_DVR_GetLastError(); log.error("获取设备工作状态失败: errorCode" + code + " errorInfo" + SdkErrorCodeEnum.getDescByCode(code)); return AjaxResult.error("获取设备工作状态失败: errorCode" + code + " errorInfo" + SdkErrorCodeEnum.getDescByCode(code)); } //图片质量 NET_DVR_JPEGPARA jpeg = new NET_DVR_JPEGPARA(); //设置图片分辨率 jpeg.wPicSize = 0; //设置图片质量 jpeg.wPicQuality = 0; IntByReference a = new IntByReference(); //设置图片大小 ByteBuffer jpegBuffer = ByteBuffer.allocate(1024 * 1024); // 抓图到内存,单帧数据捕获并保存成JPEG存放在指定的内存空间中 boolean is = hCNetSDK.NET_DVR_CaptureJPEGPicture_NEW(userId, channelNum, jpeg, jpegBuffer, 1024 * 1024, a); log.debug("-----------这里开始图片存入内存----------" + is); Base64.Encoder decoder = Base64.getEncoder(); // BASE64Encoder encoder = new BASE64Encoder(); String png_base64 = decoder.encodeToString(jpegBuffer.array());//转换成base64串 png_base64 = png_base64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n log.debug("-----------处理完成截图数据----------"); return AjaxResult.success(png_base64); } /** @@ -1927,4 +1937,112 @@ return AjaxResult.success(map); } //本地录像开始 @Override public AjaxResult localRecordStart(CameraCmd cmd) { try { String cameraId = cmd.getCameraId(); Integer channelNum = cmd.getChanNo(); String path = FileUtils.createFile("D:/LocalRecordTemp/" + cameraId + ".mp4"); if (!GlobalVariable.loginMap.containsKey(cameraId)) { return AjaxResult.error("设备未登录"); } Integer userId = (Integer) GlobalVariable.loginMap.get(cameraId); //强制I帧结构体对象 HCNetSDK.NET_DVR_I_FRAME netDvrIFrame = new HCNetSDK.NET_DVR_I_FRAME(); //新建结构体对象 netDvrIFrame.read(); netDvrIFrame.dwChannel = channelNum;//因为上文代码中设置了通道号,按照上文中的设置 netDvrIFrame.byStreamType = 0; netDvrIFrame.dwSize = netDvrIFrame.size(); netDvrIFrame.write(); if (!hCNetSDK.NET_DVR_RemoteControl(userId, 3402, netDvrIFrame.getPointer(), netDvrIFrame.dwSize)) { log.error("强制I帧 错误码为: " + hCNetSDK.NET_DVR_GetLastError()); } //预览参数 NET_DVR_PREVIEWINFO previewinfo = new NET_DVR_PREVIEWINFO(); previewinfo.read(); previewinfo.lChannel = channelNum; previewinfo.dwStreamType = 0;//码流类型:0-主码流,1-子码流,2-三码流,3-虚拟码流,以此类推 previewinfo.dwLinkMode = 0;//连接方式:0-TCP方式,1-UDP方式,2-多播方式,3-RTP方式,4-RTP/RTSP,5-RTP/HTTP,6-HRUDP(可靠传输),7-RTSP/HTTPS,8-NPQ previewinfo.hPlayWnd = null;//播放窗口的句柄,为NULL表示不解码显示。 previewinfo.bBlocked = 0;//0- 非阻塞取流,1-阻塞取流 previewinfo.byNPQMode = 0;//NPQ模式:0-直连模式,1-过流媒体模式 previewinfo.write(); if (GlobalVariable.previewMap.containsKey(cameraId)) { Integer lRealHandle = GlobalVariable.previewMap.get(cameraId); hCNetSDK.NET_DVR_StopRealPlay(lRealHandle); GlobalVariable.previewMap.remove(cameraId); log.debug("停止当前录像"); } int lRealHandle = hCNetSDK.NET_DVR_RealPlay_V40(userId, previewinfo, null, null); if (lRealHandle == -1) { int code = hCNetSDK.NET_DVR_GetLastError(); log.error("本地录像取流失败" + hCNetSDK.NET_DVR_GetLastError()); return AjaxResult.error("本地录像取流失败: errorCode:" + code + " errorInfo:" + SdkErrorCodeEnum.getDescByCode(code)); } log.debug("本地录像取流成功"); GlobalVariable.threadMap.put(cameraId, Thread.currentThread().getName()); GlobalVariable.previewMap.put(cameraId, lRealHandle); if (!hCNetSDK.NET_DVR_SaveRealData_V30(GlobalVariable.previewMap.get(cameraId), 2, path)) { int code = hCNetSDK.NET_DVR_GetLastError(); log.error("保存视频文件到临时文件夹失败 错误码为: " + hCNetSDK.NET_DVR_GetLastError()); return AjaxResult.error("本地录像取流失败: errorCode:" + code + " errorInfo:" + SdkErrorCodeEnum.getDescByCode(code)); } log.debug("本地录像开始"); return AjaxResult.success("录像开始,录像ID:" + lRealHandle); } catch (Exception ex) { log.error("本地录像开始异常" + ex.getMessage()); return AjaxResult.error("本地录像开始异常" + ex.getMessage()); } } //本地录像停止 @Override public AjaxResult localRecordStop(CameraCmd cmd) { try { String cameraId = cmd.getCameraId(); Integer channelNum = cmd.getChanNo(); String recordPath = FileUtils.createFile("D:/LocalRecordTemp/" + cameraId + ".mp4"); if (!GlobalVariable.loginMap.containsKey(cameraId)) { return AjaxResult.error("设备未登录"); } Integer userId = (Integer) GlobalVariable.loginMap.get(cameraId); //region 强制I帧 HCNetSDK.NET_DVR_I_FRAME netDvrIFrame = new HCNetSDK.NET_DVR_I_FRAME(); //新建结构体对象 netDvrIFrame.read(); netDvrIFrame.dwChannel = channelNum;//因为上文代码中设置了通道号,按照上文中的设置 netDvrIFrame.byStreamType = 0; netDvrIFrame.dwSize = netDvrIFrame.size(); netDvrIFrame.write(); if (!hCNetSDK.NET_DVR_RemoteControl(userId, 3402, netDvrIFrame.getPointer(), netDvrIFrame.dwSize)) { log.error("强制I帧 错误码为: " + hCNetSDK.NET_DVR_GetLastError()); } //endregion //region 预览参数 NET_DVR_PREVIEWINFO previewinfo = new NET_DVR_PREVIEWINFO(); previewinfo.read(); previewinfo.lChannel = channelNum; previewinfo.dwStreamType = 0;//码流类型:0-主码流,1-子码流,2-三码流,3-虚拟码流,以此类推 previewinfo.dwLinkMode = 0;//连接方式:0-TCP方式,1-UDP方式,2-多播方式,3-RTP方式,4-RTP/RTSP,5-RTP/HTTP,6-HRUDP(可靠传输),7-RTSP/HTTPS,8-NPQ previewinfo.hPlayWnd = null;//播放窗口的句柄,为NULL表示不解码显示。 previewinfo.bBlocked = 0;//0- 非阻塞取流,1-阻塞取流 previewinfo.byNPQMode = 0;//NPQ模式:0-直连模式,1-过流媒体模式 previewinfo.write(); //endregion if (GlobalVariable.previewMap.containsKey(cameraId)) { Integer lRealHandle = GlobalVariable.previewMap.get(cameraId); hCNetSDK.NET_DVR_StopRealPlay(lRealHandle); GlobalVariable.previewMap.remove(cameraId); } log.debug("本地录像停止"); byte[] recordBytes = Files.readAllBytes(Paths.get(recordPath)); //OutputStream outputStream = response.getOutputStream(); //outputStream.write(imageBytes); return AjaxResult.success(recordBytes); } catch (Exception ex) { log.error("本地录像停止异常" + ex.getMessage()); return AjaxResult.error("本地录像停止异常" +ex.getMessage()); } } }