From b5cd784d0cde5b7c82ea78aef4ac0e5a161d8c5d Mon Sep 17 00:00:00 2001
From: liusuyi <1951119284@qq.com>
Date: Mon, 18 May 2026 14:42:43 +0800
Subject: [PATCH] 优化

---
 ard-modules/ard-modules-work/src/main/java/com/ard/work/sdk/hik/service/AbstractHikVisionSDK.java |  357 +++++++++++++++++++++++++++++++++++++++--------------------
 1 files changed, 237 insertions(+), 120 deletions(-)

diff --git a/ard-modules/ard-modules-work/src/main/java/com/ard/work/sdk/hik/service/AbstractHikVisionSDK.java b/ard-modules/ard-modules-work/src/main/java/com/ard/work/sdk/hik/service/AbstractHikVisionSDK.java
index 6cfaad6..c23a459 100644
--- a/ard-modules/ard-modules-work/src/main/java/com/ard/work/sdk/hik/service/AbstractHikVisionSDK.java
+++ b/ard-modules/ard-modules-work/src/main/java/com/ard/work/sdk/hik/service/AbstractHikVisionSDK.java
@@ -5,6 +5,7 @@
 import com.ard.common.core.exception.ServiceException;
 import com.ard.common.core.exception.device.CameraSDKException;
 import com.ard.common.core.utils.StringUtils;
+import com.ard.common.core.utils.file.FileMultipartFile;
 import com.ard.common.core.utils.file.FileUtils;
 import com.ard.common.core.utils.file.MimeTypeUtils;
 import com.ard.common.redis.service.RedisService;
@@ -30,7 +31,6 @@
 import com.ard.work.sdk.model.PtzScope;
 import com.ard.work.sdk.service.CameraSDK;
 import com.ard.work.utils.FFmpegUtils;
-import com.ard.work.utils.file.MultipartFileUtil;
 import com.ard.work.utils.gis.GisUtil;
 import com.sun.jna.Native;
 import com.sun.jna.Pointer;
@@ -41,6 +41,7 @@
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.util.StopWatch;
 import org.springframework.web.multipart.MultipartFile;
+
 import java.awt.geom.Point2D;
 import java.io.ByteArrayInputStream;
 import java.io.File;
@@ -703,34 +704,41 @@
         String cameraId = cmd.getCameraId();
         Integer chanNo = cmd.getChanNo();
         int userId = cmd.getLoginId().intValue();
-
-        NET_DVR_PTZPOS m_ptzPosCurrent = new NET_DVR_PTZPOS();
-        Pointer point = m_ptzPosCurrent.getPointer();
-        IntByReference ibrBytesReturned = new IntByReference(0);
-        m_ptzPosCurrent.write();
-        boolean bool = hCNetSDK.NET_DVR_GetDVRConfig(userId, HCNetSDK.NET_DVR_GET_PTZPOS, chanNo, point,
-                m_ptzPosCurrent.size(), ibrBytesReturned);
-        if (!bool) {
-            int errorCode = hCNetSDK.NET_DVR_GetLastError();
-            String errorDesc = SdkErrorCodeEnum.getDescByCode(errorCode);
-            String errorMsg = String.format("获取ptz失败,错误码:%s,原因:%s", errorCode, errorDesc);
-            log.warn(errorMsg);
-            return null;
+        ArdCamera camera = getCamera(cameraId);
+        if ("1".equals(camera.getType())) {
+            return getPtzHigh(cmd);
+        } else {
+            NET_DVR_PTZPOS m_ptzPosCurrent = new NET_DVR_PTZPOS();
+            Pointer point = m_ptzPosCurrent.getPointer();
+            IntByReference ibrBytesReturned = new IntByReference(0);
+            m_ptzPosCurrent.write();
+            boolean bool = hCNetSDK.NET_DVR_GetDVRConfig(userId, HCNetSDK.NET_DVR_GET_PTZPOS, chanNo, point,
+                    m_ptzPosCurrent.size(), ibrBytesReturned);
+            if (!bool) {
+                int errorCode = hCNetSDK.NET_DVR_GetLastError();
+                String errorDesc = SdkErrorCodeEnum.getDescByCode(errorCode);
+                String errorMsg = String.format("获取ptz失败,错误码:%s,原因:%s", errorCode, errorDesc);
+                log.warn(errorMsg);
+                return null;
+            }
+            m_ptzPosCurrent.read();
+            // DecimalFormat df = new DecimalFormat("0.0");//设置保留位数
+            //16进制转Integer后除10,保留小数点1位
+            //实际显示的PTZ值是获取到的十六进制值的十分之一,
+            //如获取的水平参数P的值是0x1750,实际显示的P值为175度;
+            //获取到的垂直参数T的值是0x0789,实际显示的T值为78.9度;
+            //获取到的变倍参数Z的值是0x1100,实际显示的Z值为110倍。
+            BigDecimal b =
+                    BigDecimal.valueOf((float) Integer.parseInt(Integer.toHexString(m_ptzPosCurrent.wPanPos)) / 10);
+            BigDecimal c =
+                    BigDecimal.valueOf((float) Integer.parseInt(Integer.toHexString(m_ptzPosCurrent.wTiltPos)) / 10);
+            BigDecimal d =
+                    BigDecimal.valueOf((float) Integer.parseInt(Integer.toHexString(m_ptzPosCurrent.wZoomPos)) / 10);
+            float p = b.setScale(1, RoundingMode.HALF_UP).floatValue();
+            float t = c.setScale(1, RoundingMode.HALF_UP).floatValue();
+            float z = d.setScale(1, RoundingMode.HALF_UP).floatValue();
+            return new PtzDto(p, t, z);
         }
-        m_ptzPosCurrent.read();
-        // DecimalFormat df = new DecimalFormat("0.0");//设置保留位数
-        //16进制转Integer后除10,保留小数点1位
-        //实际显示的PTZ值是获取到的十六进制值的十分之一,
-        //如获取的水平参数P的值是0x1750,实际显示的P值为175度;
-        //获取到的垂直参数T的值是0x0789,实际显示的T值为78.9度;
-        //获取到的变倍参数Z的值是0x1100,实际显示的Z值为110倍。
-        BigDecimal b = BigDecimal.valueOf((float) Integer.parseInt(Integer.toHexString(m_ptzPosCurrent.wPanPos)) / 10);
-        BigDecimal c = BigDecimal.valueOf((float) Integer.parseInt(Integer.toHexString(m_ptzPosCurrent.wTiltPos)) / 10);
-        BigDecimal d = BigDecimal.valueOf((float) Integer.parseInt(Integer.toHexString(m_ptzPosCurrent.wZoomPos)) / 10);
-        float p = b.setScale(1, RoundingMode.HALF_UP).floatValue();
-        float t = c.setScale(1, RoundingMode.HALF_UP).floatValue();
-        float z = d.setScale(1, RoundingMode.HALF_UP).floatValue();
-        return new PtzDto(p, t, z);
     }
 
     /**
@@ -741,8 +749,7 @@
      * @author 刘苏义
      * @date 2024/9/5 17:00
      */
-    @Override
-    public PtzDto getPtzHigh(CameraCmd cmd) {
+    private PtzDto getPtzHigh(CameraCmd cmd) {
         try {
             String cameraId = cmd.getCameraId();
             Integer chanNo = cmd.getChanNo();
@@ -796,30 +803,39 @@
         Integer channelNum = cmd.getChanNo();
         PtzDto ptzDto = cmd.getPtzDto();
         int userId = cmd.getLoginId().intValue();
-        NET_DVR_PTZPOS m_ptzPosCurrent = new NET_DVR_PTZPOS();
-        m_ptzPosCurrent.wAction = 1;
-        try {
-            String p = String.valueOf((int) (ptzDto.getP() * 10));
-            String t = String.valueOf((int) (ptzDto.getT() * 10));
-            String z = String.valueOf((int) (ptzDto.getZ() * 10));
-            m_ptzPosCurrent.wPanPos = (short) (Integer.parseInt(p, 16));
-            m_ptzPosCurrent.wTiltPos = (short) (Integer.parseInt(t, 16));
-            m_ptzPosCurrent.wZoomPos = (short) (Integer.parseInt(z, 16));
-            Pointer point = m_ptzPosCurrent.getPointer();
-            m_ptzPosCurrent.write();
-            boolean bool = hCNetSDK.NET_DVR_SetDVRConfig(userId, NET_DVR_SET_PTZPOS, channelNum, point,
-                    m_ptzPosCurrent.size());
-            if (!bool) {
-                int errorCode = hCNetSDK.NET_DVR_GetLastError();
-                String errorDesc = SdkErrorCodeEnum.getDescByCode(errorCode);
-                String errorMsg = String.format("设置PTZ参数失败,错误码:%s,原因:%s", errorCode, errorDesc);
-                log.warn(errorMsg);
+        ArdCamera camera = getCamera(cameraId);
+        if ("1".equals(camera.getType())) {
+            DeviceCFG systemInfo = getSystemInfo(cmd);
+            if (systemInfo != null && "5.5.112".equals(systemInfo.getDwSoftwareVersion())) {
+                return setPtzHighT(cmd);
+            }
+            return setPtzHigh(cmd);
+        } else {
+            NET_DVR_PTZPOS m_ptzPosCurrent = new NET_DVR_PTZPOS();
+            m_ptzPosCurrent.wAction = 1;
+            try {
+                String p = String.valueOf((int) (ptzDto.getP() * 10));
+                String t = String.valueOf((int) (ptzDto.getT() * 10));
+                String z = String.valueOf((int) (ptzDto.getZ() * 10));
+                m_ptzPosCurrent.wPanPos = (short) (Integer.parseInt(p, 16));
+                m_ptzPosCurrent.wTiltPos = (short) (Integer.parseInt(t, 16));
+                m_ptzPosCurrent.wZoomPos = (short) (Integer.parseInt(z, 16));
+                Pointer point = m_ptzPosCurrent.getPointer();
+                m_ptzPosCurrent.write();
+                boolean bool = hCNetSDK.NET_DVR_SetDVRConfig(userId, NET_DVR_SET_PTZPOS, channelNum, point,
+                        m_ptzPosCurrent.size());
+                if (!bool) {
+                    int errorCode = hCNetSDK.NET_DVR_GetLastError();
+                    String errorDesc = SdkErrorCodeEnum.getDescByCode(errorCode);
+                    String errorMsg = String.format("设置PTZ参数失败,错误码:%s,原因:%s", errorCode, errorDesc);
+                    log.warn(errorMsg);
+                    return false;
+                }
+                return true;
+            } catch (Exception ex) {
+                log.error(ex.getMessage());
                 return false;
             }
-            return true;
-        } catch (Exception ex) {
-            log.error(ex.getMessage());
-            return false;
         }
     }
 
@@ -832,8 +848,7 @@
      * @author 刘苏义
      * @date 2024/9/5 17:04
      */
-    @Override
-    public Boolean setPtzHighT(CameraCmd cmd) {
+    private Boolean setPtzHighT(CameraCmd cmd) {
         String cameraId = cmd.getCameraId();
         Integer chanNo = cmd.getChanNo();
         PtzDto ptzDto = cmd.getPtzDto();
@@ -893,8 +908,7 @@
     }
 
     //非透传 旧设备使用 新固件会导致2通道不自动聚焦
-    @Override
-    public Boolean setPtzHigh(CameraCmd cmd) {
+    private Boolean setPtzHigh(CameraCmd cmd) {
         String cameraId = cmd.getCameraId();
         Integer chanNo = cmd.getChanNo();
         PtzDto ptzDto = cmd.getPtzDto();
@@ -1561,6 +1575,7 @@
         String type = cmd.getType() == null ? "other" : cmd.getType();
         String bucketName = cmd.getBucketName() == null ? "pic" : cmd.getBucketName();
         int userId = cmd.getLoginId().intValue();
+
         //图片信息
         NET_DVR_JPEGPARA jpeg = new NET_DVR_JPEGPARA();
         //设置图片分辨率
@@ -1570,8 +1585,9 @@
         IntByReference a = new IntByReference();
         //设置图片大小
         ByteBuffer jpegBuffer = ByteBuffer.allocate(1024 * 1024);
-        // 抓图到内存,单帧数据捕获并保存成JPEG存放在指定的内存空间中
+        // 抓图到内存
         boolean bool = hCNetSDK.NET_DVR_CaptureJPEGPicture_NEW(userId, chanNo, jpeg, jpegBuffer, 1024 * 1024, a);
+
         if (!bool) {
             int errorCode = hCNetSDK.NET_DVR_GetLastError();
             String errorDesc = SdkErrorCodeEnum.getDescByCode(errorCode);
@@ -1579,19 +1595,46 @@
             log.warn(errorMsg);
             return "";
         }
+
         log.debug("hikSdk(抓图)-结果状态值(0表示成功):{}", hCNetSDK.NET_DVR_GetLastError());
-        byte[] array = jpegBuffer.array();
-        //存储到minio
-        String objectName = cameraId + "_" + chanNo + ".jpeg";
-        InputStream inputStream = new ByteArrayInputStream(array);
-        String url = "";
-        MultipartFile multipartFile = MultipartFileUtil.inputStreamToMultipartFile(inputStream, objectName,
-                MimeTypeUtils.IMAGE_JPEG);
-        R<SysFile> sysFileR = remoteFileService.upload(multipartFile, bucketName, type);
-        if (sysFileR.getCode() == R.SUCCESS) {
-            url = sysFileR.getData().getUrl();
-            log.debug("上传文件成功:{}", url);
+
+        // 获取实际图片数据
+        int actualLength = a.getValue();
+        byte[] imageBytes;
+        if (actualLength > 0 && actualLength < 1024 * 1024) {
+            imageBytes = new byte[actualLength];
+            System.arraycopy(jpegBuffer.array(), 0, imageBytes, 0, actualLength);
+        } else {
+            imageBytes = jpegBuffer.array();
         }
+
+        // 存储到minio
+        String objectName = cameraId + "_" + chanNo + ".jpeg";
+        String url = "";
+        File tempFile = null;
+
+        try {
+            // 创建临时文件
+            tempFile = File.createTempFile("snap_", ".jpeg");
+            java.nio.file.Files.write(tempFile.toPath(), imageBytes);
+
+            // 使用 FileMultipartFile 转换
+            MultipartFile multipartFile = new FileMultipartFile(tempFile, objectName, MimeTypeUtils.IMAGE_JPEG);
+
+            R<SysFile> sysFileR = remoteFileService.upload(multipartFile, bucketName, type);
+            if (sysFileR.getCode() == R.SUCCESS) {
+                url = sysFileR.getData().getUrl();
+                log.debug("上传文件成功:{}", url);
+            }
+        } catch (Exception e) {
+            log.error("上传失败", e);
+        } finally {
+            // 删除临时文件
+            if (tempFile != null && tempFile.exists()) {
+                tempFile.delete();
+            }
+        }
+
         return url;
     }
 
@@ -1602,6 +1645,7 @@
         Integer chanNo = cmd.getChanNo();
         String type = cmd.getType() == null ? "other" : cmd.getType();
         Integer userId = cmd.getLoginId().intValue();
+
         //图片信息
         NET_DVR_JPEGPARA jpeg = new NET_DVR_JPEGPARA();
         //设置图片分辨率
@@ -1613,6 +1657,7 @@
         ByteBuffer jpegBuffer = ByteBuffer.allocate(1024 * 1024);
         // 抓图到内存,单帧数据捕获并保存成JPEG存放在指定的内存空间中
         boolean bool = hCNetSDK.NET_DVR_CaptureJPEGPicture_NEW(userId, chanNo, jpeg, jpegBuffer, 1024 * 1024, a);
+
         if (!bool) {
             int errorCode = hCNetSDK.NET_DVR_GetLastError();
             String errorDesc = SdkErrorCodeEnum.getDescByCode(errorCode);
@@ -1620,22 +1665,50 @@
             log.warn(errorMsg);
             return "";
         }
-        byte[] array = jpegBuffer.array();
-        InputStream inputStream = new ByteArrayInputStream(array);
-        String url = "";
-        MultipartFile multipartFile = MultipartFileUtil.inputStreamToMultipartFile(inputStream, objectName,
-                MimeTypeUtils.IMAGE_JPEG);
-        R<SysFile> sysFileR = remoteFileService.upload(multipartFile, bucketName, type);
-        if (sysFileR.getCode() == R.SUCCESS) {
-            url = sysFileR.getData().getUrl();
-            log.debug("上传文件成功:{}", url);
+
+        // 获取实际图片数据(只复制有效长度)
+        int actualLength = a.getValue();
+        byte[] imageBytes;
+        if (actualLength > 0 && actualLength < 1024 * 1024) {
+            imageBytes = new byte[actualLength];
+            System.arraycopy(jpegBuffer.array(), 0, imageBytes, 0, actualLength);
+        } else {
+            imageBytes = jpegBuffer.array();
         }
+
+        String url = "";
+        File tempFile = null;
+
+        try {
+            // 创建临时文件
+            tempFile = File.createTempFile("snap_", ".jpeg");
+            java.nio.file.Files.write(tempFile.toPath(), imageBytes);
+
+            // 使用 FileMultipartFile 转换
+            MultipartFile multipartFile = new FileMultipartFile(tempFile, objectName, MimeTypeUtils.IMAGE_JPEG);
+
+            R<SysFile> sysFileR = remoteFileService.upload(multipartFile, bucketName, type);
+            if (sysFileR.getCode() == R.SUCCESS) {
+                url = sysFileR.getData().getUrl();
+                log.debug("上传文件成功:{}", url);
+            }
+        } catch (Exception e) {
+            log.error("上传失败", e);
+        } finally {
+            if (tempFile != null && tempFile.exists()) {
+                tempFile.delete();
+            }
+        }
+
         return url;
     }
 
     //短时录像
     @Override
     public String record(CameraCmd cmd) {
+        String url = "";
+        File tempFile = null;
+
         try {
             String cameraId = cmd.getCameraId();
             Integer chanNo = cmd.getChanNo();
@@ -1644,29 +1717,32 @@
             String path = FileUtils.createFile(tempDir + "/record/" + name + ".mp4");
             boolean enable = cmd.isEnable();
             Integer userId = cmd.getLoginId().intValue();
+
             //强制I帧结构体对象
-            NET_DVR_I_FRAME netDvrIFrame = new NET_DVR_I_FRAME();   //新建结构体对象
+            NET_DVR_I_FRAME netDvrIFrame = new NET_DVR_I_FRAME();
             netDvrIFrame.read();
-            netDvrIFrame.dwChannel = chanNo;//因为上文代码中设置了通道号,按照上文中的设置
+            netDvrIFrame.dwChannel = chanNo;
             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 = chanNo;
-            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.dwStreamType = 0;
+            previewInfo.dwLinkMode = 0;
+            previewInfo.hPlayWnd = null;
+            previewInfo.bBlocked = 0;
+            previewInfo.byNPQMode = 0;
             previewInfo.write();
-            String url = "";
+
             if (enable) {
+                // 开始录像
                 if (!GlobalVariable.previewMap.containsKey(name)) {
                     int lRealHandle = hCNetSDK.NET_DVR_RealPlay_V40(userId, previewInfo, null, null);
                     if (lRealHandle == -1) {
@@ -1676,6 +1752,7 @@
                     log.debug("取流成功");
                     GlobalVariable.previewMap.put(name, lRealHandle);
                 }
+
                 if (!hCNetSDK.NET_DVR_SaveRealData_V30((int) GlobalVariable.previewMap.get(name), 2, path)) {
                     log.error("保存视频文件到临时文件夹失败 错误码为:{}", hCNetSDK.NET_DVR_GetLastError());
                     return "";
@@ -1683,24 +1760,40 @@
                 log.debug("录像开始");
 
             } else {
+                // 停止录像
                 if (GlobalVariable.previewMap.containsKey(name)) {
                     Integer lRealHandle = (Integer) GlobalVariable.previewMap.get(name);
                     hCNetSDK.NET_DVR_StopRealPlay(lRealHandle);
                     GlobalVariable.previewMap.remove(name);
                 }
                 log.debug("录像停止");
-                //存入minio
+
+                // 检查录像文件是否存在
+                File videoFile = new File(path);
+                if (!videoFile.exists() || videoFile.length() == 0) {
+                    log.error("录像文件不存在或为空: {}", path);
+                    return "";
+                }
+
+                // 存入minio - 使用 FileMultipartFile
                 String bucketName = "record";
-                String objectName = cameraId + "_" + chanNo;
-                MultipartFile multipartFile = MultipartFileUtil.filePathToMultipartFile(path, objectName,
-                        MimeTypeUtils.VIDEO_MP4);
+                String objectName = cameraId + "_" + chanNo + ".mp4";
+
+                // 创建临时文件对象(实际上 path 已经是文件路径)
+                tempFile = new File(path);
+
+                // 使用 FileMultipartFile 转换
+                MultipartFile multipartFile = new FileMultipartFile(tempFile, objectName, MimeTypeUtils.VIDEO_MP4);
+
                 R<SysFile> sysFileR = remoteFileService.upload(multipartFile, bucketName);
                 if (sysFileR.getCode() == R.SUCCESS) {
                     url = sysFileR.getData().getUrl();
                     log.debug("上传文件成功:{}", url);
                 }
             }
+
             return url;
+
         } catch (Exception ex) {
             log.error("录像异常:{}", ex.getMessage());
             return "";
@@ -1767,65 +1860,78 @@
     @Override
     public String recordStop(CameraCmd cmd) {
         String url = "";
+        File videoFile = null;
+        File transcodeFile = null;
+
         try {
             String cameraId = cmd.getCameraId();
             Integer chanNo = cmd.getChanNo();
             String name = cameraId + "_" + chanNo;
             // 本地临时录像地址
             String path = FileUtils.createFile(tempDir + "/record/" + name + ".mp4");
-            Integer userId = cmd.getLoginId().intValue();
-            //region 强制I帧
-            NET_DVR_I_FRAME netDvrIFrame = new NET_DVR_I_FRAME();   //新建结构体对象
-            netDvrIFrame.read();
-            netDvrIFrame.dwChannel = chanNo;//因为上文代码中设置了通道号,按照上文中的设置
-            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 = chanNo;
-            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(name)) {
                 Integer lRealHandle = (Integer) GlobalVariable.previewMap.get(name);
                 hCNetSDK.NET_DVR_StopRealPlay(lRealHandle);
                 GlobalVariable.previewMap.remove(name);
             }
             log.debug("录像停止");
-            //ffmpeg转码
+
+            // 检查原录像文件是否存在
+            videoFile = new File(path);
+            if (!videoFile.exists() || videoFile.length() == 0) {
+                log.error("录像文件不存在或为空: {}", path);
+                return "";
+            }
+
+            // ffmpeg转码
             StopWatch watchStop = new StopWatch();
             watchStop.start();
             String newpath = FileUtils.createFile(tempDir + "/record/" + name + "_c.mp4");
+            transcodeFile = new File(newpath);
             FFmpegUtils.transcodeToMP4(path, newpath);
             watchStop.stop();
             log.warn("转码耗时:{}", watchStop.getTotalTimeMillis());
-            //存入minio
+
+            // 检查转码后的文件是否存在
+            if (!transcodeFile.exists() || transcodeFile.length() == 0) {
+                log.error("转码文件不存在或为空: {}", newpath);
+                return "";
+            }
+
+            // 存入minio - 使用 FileMultipartFile
             String bucketName = "record";
-            String objectName = cameraId + "_" + chanNo;
+            String objectName = cameraId + "_" + chanNo + ".mp4";
             String type = cmd.getType();
-            MultipartFile multipartFile = MultipartFileUtil.filePathToMultipartFile(newpath, objectName,
-                    MimeTypeUtils.VIDEO_MP4);
+
+            MultipartFile multipartFile = new FileMultipartFile(transcodeFile, objectName, MimeTypeUtils.VIDEO_MP4);
             R<SysFile> sysFileR = remoteFileService.upload(multipartFile, bucketName, type);
+
             if (sysFileR.getCode() == R.SUCCESS) {
                 url = sysFileR.getData().getUrl();
                 log.info("上传文件成功:{}", url);
             }
 
             return url;
+
         } catch (Exception ex) {
             log.error("录像异常:{}", ex.getMessage());
             return "";
+        } finally {
+            // 清理临时文件
+            try {
+                if (videoFile != null && videoFile.exists()) {
+                    videoFile.delete();
+                    log.debug("删除原录像文件: {}", videoFile.getPath());
+                }
+                if (transcodeFile != null && transcodeFile.exists()) {
+                    transcodeFile.delete();
+                    log.debug("删除转码文件: {}", transcodeFile.getPath());
+                }
+            } catch (Exception e) {
+                log.warn("删除临时文件失败", e);
+            }
         }
     }
 
@@ -1891,7 +1997,7 @@
                         camera.getRtspPort(),
                         channel.getChanNo()
                 );
-                channel.setRtspUrl(rtspUrl);
+                channel.setLiveAddress(rtspUrl);
                 channelList.add(channel);
             }
         }
@@ -2343,4 +2449,15 @@
             return true;
         }
     }
+
+    /**
+     * 获取相机信息(会校验存在性)
+     */
+    private ArdCamera getCamera(String cameraId) {
+        ArdCamera camera = redisService.getCacheMapValue(CacheConstants.CAMERA_LIST, cameraId);
+        if (camera == null) {
+            throw CameraSDKException.cameraNotExist(cameraId);
+        }
+        return camera;
+    }
 }

--
Gitblit v1.9.3