From dae6e068207ad1bff32dafd8c71f12d8a2a59aa2 Mon Sep 17 00:00:00 2001
From: aijinhui <aijinhui>
Date: Mon, 15 Apr 2024 16:21:03 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev

---
 ard-work/src/main/java/com/ruoyi/utils/sdk/hiksdk/controller/HikSdkController.java        |    7 
 ard-work/src/main/java/com/ruoyi/utils/sdk/common/SdkErrorCodeEnum.java                   |    3 
 ard-work/src/main/java/com/ruoyi/utils/sdk/dhsdk/module/RealPlayModule.java               |    4 
 ard-work/src/main/java/com/ruoyi/device/camera/factory/CameraSDK.java                     |   11 
 ard-work/src/main/java/com/ruoyi/device/camera/controller/CameraSdkController.java        |   54 ++++
 ard-work/src/main/java/com/ruoyi/device/camera/service/impl/CameraSdkServiceImpl.java     |   60 ++++
 ard-work/src/main/java/com/ruoyi/utils/qymqtt/oldM/PushCallback.java                      |    2 
 ard-work/src/main/java/com/ruoyi/utils/sdk/hiksdk/service/impl/HikvisionSDK.java          |  196 ++++++++++++---
 ard-work/src/main/java/com/ruoyi/device/camera/service/ICameraSdkService.java             |   10 
 ard-work/src/main/java/com/ruoyi/utils/sdk/dhsdk/module/LoginModule.java                  |    2 
 ard-work/src/main/java/com/ruoyi/alarm/global/service/impl/QueueHandler.java              |   25 +
 ard-work/src/main/java/com/ruoyi/inspect/service/impl/ArdVideoInspectTaskServiceImpl.java |   64 +++-
 ard-work/src/main/java/com/ruoyi/sy/service/impl/ArdSyCarServiceImpl.java                 |  112 +++++----
 ard-work/src/main/java/com/ruoyi/utils/sdk/dhsdk/service/impl/DahuaSDK.java               |  155 +++++++++++-
 14 files changed, 541 insertions(+), 164 deletions(-)

diff --git a/ard-work/src/main/java/com/ruoyi/alarm/global/service/impl/QueueHandler.java b/ard-work/src/main/java/com/ruoyi/alarm/global/service/impl/QueueHandler.java
index 05ebddc..0c705c4 100644
--- a/ard-work/src/main/java/com/ruoyi/alarm/global/service/impl/QueueHandler.java
+++ b/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()) {
diff --git a/ard-work/src/main/java/com/ruoyi/device/camera/controller/CameraSdkController.java b/ard-work/src/main/java/com/ruoyi/device/camera/controller/CameraSdkController.java
index a2cefc6..1568ce7 100644
--- a/ard-work/src/main/java/com/ruoyi/device/camera/controller/CameraSdkController.java
+++ b/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);
+    }
 }
diff --git a/ard-work/src/main/java/com/ruoyi/device/camera/factory/CameraSDK.java b/ard-work/src/main/java/com/ruoyi/device/camera/factory/CameraSDK.java
index a978e5a..c1d51b5 100644
--- a/ard-work/src/main/java/com/ruoyi/device/camera/factory/CameraSDK.java
+++ b/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);
 }
diff --git a/ard-work/src/main/java/com/ruoyi/device/camera/service/ICameraSdkService.java b/ard-work/src/main/java/com/ruoyi/device/camera/service/ICameraSdkService.java
index 8909eec..18f0cde 100644
--- a/ard-work/src/main/java/com/ruoyi/device/camera/service/ICameraSdkService.java
+++ b/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);
 }
diff --git a/ard-work/src/main/java/com/ruoyi/device/camera/service/impl/CameraSdkServiceImpl.java b/ard-work/src/main/java/com/ruoyi/device/camera/service/impl/CameraSdkServiceImpl.java
index de2805a..e3aac54 100644
--- a/ard-work/src/main/java/com/ruoyi/device/camera/service/impl/CameraSdkServiceImpl.java
+++ b/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());
+        }
+    }
 }
diff --git a/ard-work/src/main/java/com/ruoyi/inspect/service/impl/ArdVideoInspectTaskServiceImpl.java b/ard-work/src/main/java/com/ruoyi/inspect/service/impl/ArdVideoInspectTaskServiceImpl.java
index 097c4fa..50701bc 100644
--- a/ard-work/src/main/java/com/ruoyi/inspect/service/impl/ArdVideoInspectTaskServiceImpl.java
+++ b/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;
@@ -457,6 +458,14 @@
                     if (setTargetPosition) {
                         /*控制相机巡检成功,开始录像*/
                         cameraSdkService.recordStart(cmd);
+                        //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
                     } else {
                         /*控制失败,当前步骤启动时间置null*/
                         ardVideoInspectTask.setCurrentStepStartTime("");
@@ -517,6 +526,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
                     }
                 }
             }
@@ -652,32 +669,35 @@
     public List getCameraIdleTimeList(String cameraId) {
         LinkedList<String> timeList = new LinkedList();
         List<Map> usedPeriods = this.getTaskUsedCameraPeriods(cameraId);
-        for (Map p :
-                usedPeriods) {
-            timeList.add((String) p.get("start_time"));
-            timeList.add((String) p.get("end_time"));
-        }
-        //判断第一个起始点
-        if (timeList.size() > 0) {
-            if ("00:00:00".equals(timeList.getFirst())) {
-                timeList.removeFirst();
-            } else {
-                timeList.addFirst("00:00:00");
+        //事件段为空,则全天作为一个时间段
+        if (usedPeriods.size() == 0) {
+            timeList.add("00:00:00");
+            timeList.add("23:59:59");
+        }else{
+            for (Map p :
+                    usedPeriods) {
+                timeList.add((String) p.get("start_time"));
+                timeList.add((String) p.get("end_time"));
             }
-            //判断最后一个结束时间
-            if ("23:59:59".equals(timeList.getLast())) {
-                timeList.removeLast();
-            } else {
-                timeList.addLast("23:59:59");
-            }
-            //事件段为空,则全天作为一个时间段
-            if (timeList.size() == 0) {
-                timeList.add("00:00:00");
-                timeList.add("23:59:59");
-            }
+            //判断第一个起始点
+            if (timeList.size() > 0) {
+                if ("00:00:00".equals(timeList.getFirst())) {
+                    timeList.removeFirst();
+                } else {
+                    timeList.addFirst("00:00:00");
+                }
+                //判断最后一个结束时间
+                if ("23:59:59".equals(timeList.getLast())) {
+                    timeList.removeLast();
+                } else {
+                    timeList.addLast("23:59:59");
+                }
 
+
+            }
         }
 
+
         return timeList;
     }
 }
diff --git a/ard-work/src/main/java/com/ruoyi/sy/service/impl/ArdSyCarServiceImpl.java b/ard-work/src/main/java/com/ruoyi/sy/service/impl/ArdSyCarServiceImpl.java
index baa6568..118dcdf 100644
--- a/ard-work/src/main/java/com/ruoyi/sy/service/impl/ArdSyCarServiceImpl.java
+++ b/ard-work/src/main/java/com/ruoyi/sy/service/impl/ArdSyCarServiceImpl.java
@@ -1317,62 +1317,70 @@
      */
     @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");
+                if(carGPSMap.size()>0) {
+                    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;
     }
     /**
      * 获取范围内的车辆信息(多边形)
diff --git a/ard-work/src/main/java/com/ruoyi/utils/qymqtt/oldM/PushCallback.java b/ard-work/src/main/java/com/ruoyi/utils/qymqtt/oldM/PushCallback.java
index a955c6a..37841aa 100644
--- a/ard-work/src/main/java/com/ruoyi/utils/qymqtt/oldM/PushCallback.java
+++ b/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("连接断开,正在重连....");
         }
     }
 
diff --git a/ard-work/src/main/java/com/ruoyi/utils/sdk/common/SdkErrorCodeEnum.java b/ard-work/src/main/java/com/ruoyi/utils/sdk/common/SdkErrorCodeEnum.java
index 7cad149..64832aa 100644
--- a/ard-work/src/main/java/com/ruoyi/utils/sdk/common/SdkErrorCodeEnum.java
+++ b/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已注销或不可用");
     /**
      * 枚举码
      */
diff --git a/ard-work/src/main/java/com/ruoyi/utils/sdk/dhsdk/module/LoginModule.java b/ard-work/src/main/java/com/ruoyi/utils/sdk/dhsdk/module/LoginModule.java
index ff36514..ee3b54a 100644
--- a/ard-work/src/main/java/com/ruoyi/utils/sdk/dhsdk/module/LoginModule.java
+++ b/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);//
diff --git a/ard-work/src/main/java/com/ruoyi/utils/sdk/dhsdk/module/RealPlayModule.java b/ard-work/src/main/java/com/ruoyi/utils/sdk/dhsdk/module/RealPlayModule.java
index a1afd9f..76fb17b 100644
--- a/ard-work/src/main/java/com/ruoyi/utils/sdk/dhsdk/module/RealPlayModule.java
+++ b/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 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/ard-work/src/main/java/com/ruoyi/utils/sdk/dhsdk/service/impl/DahuaSDK.java b/ard-work/src/main/java/com/ruoyi/utils/sdk/dhsdk/service/impl/DahuaSDK.java
index e7ce57e..85e0da4 100644
--- a/ard-work/src/main/java/com/ruoyi/utils/sdk/dhsdk/service/impl/DahuaSDK.java
+++ b/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.*;
@@ -270,16 +274,12 @@
 
     //创建引导队列
     private void createGuideQueue(ArdCameras camera) {
-        if (camera.getCamAlarmGuideEnable() != null) {
-            if (camera.getCamAlarmGuideEnable() == 1) {
-                if (!GuidePriorityQueue.cameraQueueMap.containsKey(camera.getId())) {
-                    Comparator<GuideTask> comparator = GuidePriorityQueue.getComparator();
-                    PriorityBlockingQueue<GuideTask> priorityQueue = new PriorityBlockingQueue<>(1000, comparator);
-                    GuidePriorityQueue.cameraQueueMap.put(camera.getId(), priorityQueue);
-                    //启动队列处理器
-                    queueHandler.process(camera.getId());
-                }
-            }
+        if (!GuidePriorityQueue.cameraQueueMap.containsKey(camera.getId())) {
+            Comparator<GuideTask> comparator = GuidePriorityQueue.getComparator();
+            PriorityBlockingQueue<GuideTask> priorityQueue = new PriorityBlockingQueue<>(1000, comparator);
+            GuidePriorityQueue.cameraQueueMap.put(camera.getId(), priorityQueue);
+            //启动队列处理器
+            queueHandler.process(camera.getId());
         }
     }
 
@@ -550,6 +550,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 +834,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 +969,6 @@
         return AjaxResult.success("该功能未实现");
     }
 
-    @Override
-    public AjaxResult captureJPEGPicture(CameraCmd cmd) {
-        return AjaxResult.success("该功能未实现");
-    }
 
     //切换透雾
     @Override
@@ -1125,4 +1215,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();
+                }
+            }
+        }
+    }
 }
diff --git a/ard-work/src/main/java/com/ruoyi/utils/sdk/hiksdk/controller/HikSdkController.java b/ard-work/src/main/java/com/ruoyi/utils/sdk/hiksdk/controller/HikSdkController.java
index e92f0a2..0c3a555 100644
--- a/ard-work/src/main/java/com/ruoyi/utils/sdk/hiksdk/controller/HikSdkController.java
+++ b/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("相机抓图")
diff --git a/ard-work/src/main/java/com/ruoyi/utils/sdk/hiksdk/service/impl/HikvisionSDK.java b/ard-work/src/main/java/com/ruoyi/utils/sdk/hiksdk/service/impl/HikvisionSDK.java
index 3f8969b..b8dcd9c 100644
--- a/ard-work/src/main/java/com/ruoyi/utils/sdk/hiksdk/service/impl/HikvisionSDK.java
+++ b/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;
@@ -284,16 +287,12 @@
 
     //创建引导队列
     private void createGuideQueue(ArdCameras camera) {
-        if (camera.getCamAlarmGuideEnable() != null) {
-            if (camera.getCamAlarmGuideEnable() == 1) {
-                if (!GuidePriorityQueue.cameraQueueMap.containsKey(camera.getId())) {
-                    Comparator<GuideTask> comparator = GuidePriorityQueue.getComparator();
-                    PriorityBlockingQueue<GuideTask> priorityQueue = new PriorityBlockingQueue<>(1000, comparator);
-                    GuidePriorityQueue.cameraQueueMap.put(camera.getId(), priorityQueue);
-                    //启动队列处理器
-                    queueHandler.process(camera.getId());
-                }
-            }
+        if (!GuidePriorityQueue.cameraQueueMap.containsKey(camera.getId())) {
+            Comparator<GuideTask> comparator = GuidePriorityQueue.getComparator();
+            PriorityBlockingQueue<GuideTask> priorityQueue = new PriorityBlockingQueue<>(1000, comparator);
+            GuidePriorityQueue.cameraQueueMap.put(camera.getId(), priorityQueue);
+            //启动队列处理器
+            queueHandler.process(camera.getId());
         }
     }
 
@@ -1497,38 +1496,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 +1933,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());
+        }
+    }
 }

--
Gitblit v1.9.3