‘liusuyi’
2024-04-13 a17ac1c04c229294760d58825ac68dbe044e8278
增加本地抓图和录像 增加兴趣点引导上报
已修改14个文件
616 ■■■■ 文件已修改
ard-work/src/main/java/com/ruoyi/alarm/global/service/impl/QueueHandler.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/camera/controller/CameraSdkController.java 54 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/camera/factory/CameraSDK.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/camera/service/ICameraSdkService.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/camera/service/impl/CameraSdkServiceImpl.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/inspect/service/impl/ArdVideoInspectTaskServiceImpl.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/sy/service/impl/ArdSyCarServiceImpl.java 110 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/utils/qymqtt/oldM/PushCallback.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/utils/sdk/common/SdkErrorCodeEnum.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/utils/sdk/dhsdk/module/LoginModule.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/utils/sdk/dhsdk/module/RealPlayModule.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/utils/sdk/dhsdk/service/impl/DahuaSDK.java 139 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/utils/sdk/hiksdk/controller/HikSdkController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/utils/sdk/hiksdk/service/impl/HikvisionSDK.java 180 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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());
        }
    }
}