Bladeren bron

确实大华事件时, 将视频上传到文件服务器.

Memory_LG 4 dagen geleden
bovenliggende
commit
4ed7247889

+ 17 - 6
pom.xml

@@ -92,7 +92,7 @@
         <dependency>
             <groupId>com.dahuatech.icc</groupId>
             <artifactId>java-sdk-oauth</artifactId>
-            <version>1.0.9</version>
+            <version>1.0.13.10</version>
             <exclusions>
                 <exclusion>
                     <artifactId>java-sdk-core</artifactId>
@@ -101,11 +101,11 @@
             </exclusions>
         </dependency>
 
-        <dependency>
-            <groupId>com.dahuatech.icc</groupId>
-            <artifactId>java-sdk-core</artifactId>
-            <version>1.0.9</version>
-        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>com.dahuatech.icc</groupId>-->
+<!--            <artifactId>java-sdk-core</artifactId>-->
+<!--            <version>1.0.9</version>-->
+<!--        </dependency>-->
 
         <!-- mp4文件操作jar -->
         <!-- https://mvnrepository.com/artifact/com.googlecode.mp4parser/isoparser -->
@@ -120,6 +120,17 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-websocket</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.dahuatech.icc</groupId>
+            <artifactId>java-sdk-oauth</artifactId>
+            <version>1.0.13.10</version>
+        </dependency>
     </dependencies>
 
     <build>

+ 6 - 0
src/main/java/com/sooka/sponest/monitor/dahua/controller/DahuaController.java

@@ -9,6 +9,7 @@ import com.ruoyi.common.security.utils.SecurityUtils;
 import com.ruoyi.system.api.domain.SysUser;
 import com.ruoyi.system.api.model.LoginUser;
 import com.sooka.sponest.monitor.dahua.domain.CenterdataTAttach;
+import com.sooka.sponest.monitor.dahua.domain.DaHuaMp4VO;
 import com.sooka.sponest.monitor.dahua.service.DahuaService;
 import com.sooka.sponest.monitor.remoteapi.service.center.system.RemoteService;
 import io.swagger.annotations.Api;
@@ -294,4 +295,9 @@ public class DahuaController {
         return dahuaService.cameraSteering(lng,lat,list);
     }
 
+    @PostMapping("/reportMp4ToFileService")
+    public AjaxResult reportMp4ToFileService(@RequestBody DaHuaMp4VO mp4VO) throws IOException, ClientException {
+        return dahuaService.reportMp4ToFileService(mp4VO);
+    }
+
 }

+ 19 - 0
src/main/java/com/sooka/sponest/monitor/dahua/domain/DaHuaMp4VO.java

@@ -0,0 +1,19 @@
+package com.sooka.sponest.monitor.dahua.domain;
+
+
+import lombok.*;
+import org.apache.ibatis.type.Alias;
+
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+@ToString
+@Alias("daHuaMp4VO")
+public class DaHuaMp4VO {
+    private String chnnaleCode;
+    private String alarmCode;
+    private String logId;
+    private String eventCode;
+
+}

+ 4 - 0
src/main/java/com/sooka/sponest/monitor/dahua/service/DahuaService.java

@@ -5,7 +5,9 @@ import com.dahuatech.hutool.json.JSONObject;
 import com.dahuatech.icc.exception.ClientException;
 import com.ruoyi.common.core.web.domain.AjaxResult;
 import com.sooka.sponest.monitor.dahua.domain.CenterdataTAttach;
+import com.sooka.sponest.monitor.dahua.domain.DaHuaMp4VO;
 
+import java.io.IOException;
 import java.util.List;
 
 public interface DahuaService {
@@ -114,4 +116,6 @@ public interface DahuaService {
     * @date 2025/8/19 上午9:26
     */
     AjaxResult cameraSteering(Double lng, Double lat, List<String> list);
+
+    AjaxResult reportMp4ToFileService(DaHuaMp4VO mp4VO) throws IOException, ClientException;
 }

+ 50 - 14
src/main/java/com/sooka/sponest/monitor/dahua/service/impl/DahuaServiceImpl.java

@@ -1,6 +1,5 @@
 package com.sooka.sponest.monitor.dahua.service.impl;
 
-import com.alibaba.druid.support.json.JSONUtils;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.nacos.shaded.com.google.gson.Gson;
 import com.dahuatech.hutool.core.codec.Base64;
@@ -28,6 +27,7 @@ import com.sooka.sponest.monitor.camera.domain.CentermonitorTCameraStateLog;
 import com.sooka.sponest.monitor.camera.mapper.CentermonitorTCameraMapper;
 import com.sooka.sponest.monitor.camera.service.ICentermonitorTCameraService;
 import com.sooka.sponest.monitor.dahua.domain.CenterdataTAttach;
+import com.sooka.sponest.monitor.dahua.domain.DaHuaMp4VO;
 import com.sooka.sponest.monitor.dahua.domain.PlayBackProperties;
 import com.sooka.sponest.monitor.dahua.service.DahuaService;
 import com.sooka.sponest.monitor.dahua.utils.HttpEnum;
@@ -38,13 +38,16 @@ import com.sooka.sponest.monitor.remoteapi.service.center.event.RemoteEventBaseS
 import com.sooka.sponest.monitor.remoteapi.service.center.event.domain.CentereventTDownloads;
 import com.sooka.sponest.monitor.remoteapi.service.center.file.RemoteFileBaseService;
 import com.sooka.sponest.monitor.util.Mp4ParserUtils;
+import com.sooka.sponest.monitor.util.VideoUrlFetcher;
 import org.apache.commons.collections4.CollectionUtils;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
 import javax.crypto.Cipher;
 import java.io.File;
+import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.security.KeyFactory;
 import java.security.interfaces.RSAPublicKey;
@@ -53,6 +56,8 @@ import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.*;
 
+import static com.sooka.sponest.monitor.util.Mp4ParserUtils.convertUrlToMultipartFile;
+
 @Service
 public class DahuaServiceImpl extends BaseService implements DahuaService {
 
@@ -151,6 +156,7 @@ public class DahuaServiceImpl extends BaseService implements DahuaService {
             redisService.expire("DH_TOKEN", 60 * 60 * 2 - 60);
             return token;
         } catch (Exception e) {
+            log.error(e.getMessage());
             return token;
         }
     }
@@ -508,7 +514,6 @@ public class DahuaServiceImpl extends BaseService implements DahuaService {
     }
 
 
-
     /**
      * 获取执法记录仪token
      */
@@ -551,9 +556,9 @@ public class DahuaServiceImpl extends BaseService implements DahuaService {
     }
 
     public AjaxResult getPlaybackByTime(String properties) {
-        log.info("**GetPlaybackByTime->"+new Date()+"->start**");
+        log.info("**GetPlaybackByTime->" + new Date() + "->start**");
         List<PlayBackProperties> propertiesList = JSON.parseArray(properties, PlayBackProperties.class);
-        for (PlayBackProperties property: propertiesList) {
+        for (PlayBackProperties property : propertiesList) {
             //下载并上传视频
             AjaxResult ajaxResult = getPlaybackByTime(property);
             //将视频下载结果保存至事件中心
@@ -566,7 +571,7 @@ public class DahuaServiceImpl extends BaseService implements DahuaService {
             downloads.setReason(ajaxResult.get("msg").toString());
             eventBaseService.downloads(downloads);
         }
-        log.info("**GetPlaybackByTime->"+new Date()+"->end**");
+        log.info("**GetPlaybackByTime->" + new Date() + "->end**");
         return AjaxResult.success();
     }
 
@@ -667,10 +672,10 @@ public class DahuaServiceImpl extends BaseService implements DahuaService {
                     //清空文件夹
                     File folder = new File(dssFileDownloadUrl);
                     File[] files = folder.listFiles();
-                    if (files != null){
+                    if (files != null) {
                         for (File f : files) {
                             boolean b = f.delete();
-                            if(!b) log.error("getPlaybackByTime => 文件删除失败!");
+                            if (!b) log.error("getPlaybackByTime => 文件删除失败!");
                         }
                     }
                 } else {
@@ -678,14 +683,13 @@ public class DahuaServiceImpl extends BaseService implements DahuaService {
                 }
                 return AjaxResult.success("文件下载成功", sysFileR.getData().getUrl());
             }
-        }else {
+        } else {
             log.error("getPlaybackByTime-查询大华录像-{}, result => {}", "录像回放接口报错", JSONUtil.toJsonStr(QueryRecordsResult));
             return AjaxResult.error("录像回放接口报错", QueryRecordsResult.getStr("desc"));
         }
     }
 
 
-
     public JSONObject IccHttpHttpRequest(String url, Method method, String param, String token, String action) {
         log.info("----开始执行----{}------请求参数:{}", action, JSONUtil.toJsonStr(param));
         String prBody;
@@ -775,11 +779,11 @@ public class DahuaServiceImpl extends BaseService implements DahuaService {
     }
 
     /*
-    * 大华联动调转摄像头指向
-    *
-    * @author 韩福成
-    * @date 2025/8/19 上午9:26
-    */
+     * 大华联动调转摄像头指向
+     *
+     * @author 韩福成
+     * @date 2025/8/19 上午9:26
+     */
     public AjaxResult cameraSteering(Double lng, Double lat, List<String> list) {
         List<String> creamList = centermonitorTCameraMapper.getCreamList(list);
         if (CollectionUtils.isEmpty(creamList)) {
@@ -806,4 +810,36 @@ public class DahuaServiceImpl extends BaseService implements DahuaService {
         return AjaxResult.success();
     }
 
+    @Override
+    public AjaxResult reportMp4ToFileService(DaHuaMp4VO mp4VO) throws IOException, ClientException {
+        String token = dahuaService.getToken();
+        String baseUrl = host+"/evo-apigw/evo-gmai/1.4.0/ai/history/task/getAlarmVideo";
+        String downloadUrl = host+"/evo-apigw/evo-oss/";
+        //发送get请求, 获取MP4地址.
+        String videoUrl = downloadUrl + VideoUrlFetcher.getVideoUrl(baseUrl, mp4VO.getChnnaleCode(), mp4VO.getAlarmCode(), token) + "?token="+token;
+        try {
+            //上传到文件服务器
+            R<SysFile> sysFileR = fileBaseService.upload(convertUrlToMultipartFile(videoUrl));
+            if (sysFileR.getCode() == 200) {
+                log.info("getPlaybackByTime => 文件上传成功!{}", sysFileR.getData().getUrl());
+                //保存到数据中心
+                /*CenterdataTAttach attach = new CenterdataTAttach();
+                attach.setBusId(mp4VO.getLogId());
+                attach.setAttachPath(sysFileR.getData().getUrl());
+                attach.setFileName(sysFileR.getData().getName());
+                attach.setBusSource("PC");
+                attach.setFileType("video");
+                dataBaseService.insertAttach(attach);*/
+            } else {
+                log.info("getPlaybackByTime => 文件上传失败!{}", sysFileR.getMsg());
+            }
+
+            return AjaxResult.success("下载成功");
+        } catch (IOException e) {
+            e.printStackTrace();
+            return AjaxResult.error(e.getMessage());
+        }
+    }
+
+
 }

+ 70 - 0
src/main/java/com/sooka/sponest/monitor/util/Mp4ParserUtils.java

@@ -11,10 +11,13 @@ import com.googlecode.mp4parser.authoring.tracks.CroppedTrack;
 import org.apache.commons.fileupload.FileItem;
 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
 import org.springframework.http.MediaType;
+import org.springframework.mock.web.MockMultipartFile;
 import org.springframework.web.multipart.MultipartFile;
 import org.springframework.web.multipart.commons.CommonsMultipartFile;
 
 import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
 import java.nio.channels.FileChannel;
 import java.nio.file.Files;
 import java.util.ArrayList;
@@ -241,4 +244,71 @@ public class Mp4ParserUtils {
         return timeOfSyncSamples[timeOfSyncSamples.length - 1];
     }
 
+    public static MultipartFile convertUrlToMultipartFile(String fileUrl) throws IOException {
+
+        SSLUtils.disableSSLVerification(); // 禁用 SSL 验证
+        // 创建 URL 对象
+        URL url = new URL(fileUrl);
+        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
+
+        // 设置请求方式和超时时间
+        httpURLConnection.setRequestMethod("GET");
+        httpURLConnection.setConnectTimeout(5000);
+        httpURLConnection.setReadTimeout(5000);
+
+        // 检查响应码
+        int responseCode = httpURLConnection.getResponseCode();
+        if (responseCode != 200) {
+            throw new IOException("Failed to download file. Response code: " + responseCode);
+        }
+
+        // 获取输入流
+        InputStream inputStream = httpURLConnection.getInputStream();
+
+        // 获取文件名
+        String fileName = url.getFile();
+//        fileName = fileName.substring(fileName.lastIndexOf('/') + 1);
+
+
+        int lastSlashIndex = fileName.lastIndexOf('/');
+        int questionMarkIndex = fileName.indexOf('?', lastSlashIndex);
+
+        if (questionMarkIndex != -1) {
+            fileName = fileName.substring(lastSlashIndex + 1, questionMarkIndex);
+        } else {
+            fileName = fileName.substring(lastSlashIndex + 1);
+        }
+
+
+        // 创建一个临时文件
+        File tempFile = File.createTempFile("temp", fileName);
+        tempFile.deleteOnExit();
+
+        // 将输入流的内容写入临时文件
+        try (OutputStream outputStream = new FileOutputStream(tempFile)) {
+            byte[] buffer = new byte[4096];
+            int bytesRead;
+            while ((bytesRead = inputStream.read(buffer)) != -1) {
+                outputStream.write(buffer, 0, bytesRead);
+            }
+        }
+
+        // 关闭输入流
+        inputStream.close();
+
+        // 从临时文件创建 MultipartFile
+        FileInputStream fileInputStream = new FileInputStream(tempFile);
+        MultipartFile multipartFile = new MockMultipartFile(
+                fileName,
+                fileName,
+                "video/mp4",
+                fileInputStream
+        );
+
+        // 关闭文件输入流
+        fileInputStream.close();
+
+        return multipartFile;
+    }
+
 }

+ 46 - 0
src/main/java/com/sooka/sponest/monitor/util/SSLUtils.java

@@ -0,0 +1,46 @@
+package com.sooka.sponest.monitor.util;
+
+import javax.net.ssl.*;
+import java.security.cert.X509Certificate;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+public class SSLUtils {
+    public static void disableSSLVerification() {
+        try {
+            // 创建一个不验证主机名的 HostnameVerifier
+            HostnameVerifier allHostsValid = new HostnameVerifier() {
+                public boolean verify(String hostname, SSLSession session) {
+                    return true;
+                }
+            };
+
+            // 安装 HostnameVerifier
+            HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
+
+            // 创建一个信任所有证书的 TrustManager
+            TrustManager[] trustAllCerts = new TrustManager[]{
+                    new X509TrustManager() {
+                        public X509Certificate[] getAcceptedIssuers() {
+                            return new X509Certificate[]{};
+                        }
+
+                        public void checkClientTrusted(X509Certificate[] certs, String authType) {
+                        }
+
+                        public void checkServerTrusted(X509Certificate[] certs, String authType) {
+                        }
+                    }
+            };
+
+            // 安装 TrustManager
+            SSLContext sc = SSLContext.getInstance("SSL");
+            sc.init(null, trustAllCerts, new java.security.SecureRandom());
+            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
+

+ 111 - 0
src/main/java/com/sooka/sponest/monitor/util/VideoUrlFetcher.java

@@ -0,0 +1,111 @@
+package com.sooka.sponest.monitor.util;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.ssl.SSLContextBuilder;
+import org.apache.http.util.EntityUtils;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import javax.net.ssl.SSLContext;
+import java.io.IOException;
+import java.net.URI;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.Map;
+import org.springframework.mock.web.MockMultipartFile;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+public class VideoUrlFetcher {
+    public static String getVideoUrl(String baseUrl, String channelCode, String alarmCode, String token) throws IOException {
+        try {
+            // 构建请求 URL
+            String url = baseUrl + "?chnnaleCode=" + channelCode + "&alarmCode=" + alarmCode;
+            System.out.println("url = " + url);
+
+            // 创建忽略 SSL 验证的 HttpClient 实例
+            HttpClient httpClient = createHttpClient();
+
+            // 创建 HttpGet 请求
+            HttpGet httpGet = new HttpGet(url);
+
+            // 设置请求头中的 token
+            httpGet.setHeader("authorization", "bearer "+token);
+
+            // 执行请求
+            HttpResponse response = httpClient.execute(httpGet);
+
+            // 获取响应状态码
+            int statusCode = response.getStatusLine().getStatusCode();
+            if (statusCode != 200) {
+                throw new IOException("请求失败,状态码: " + statusCode);
+            }
+
+            // 获取响应内容
+            String responseBody = EntityUtils.toString(response.getEntity());
+
+            // 使用 Jackson 解析 JSON 响应
+            ObjectMapper objectMapper = new ObjectMapper();
+            Map<String, Object> responseMap = objectMapper.readValue(responseBody, HashMap.class);
+
+            // 检查请求是否成功
+            boolean success = (boolean) responseMap.get("success");
+            if (!success) {
+                String errMsg = (String) responseMap.get("errMsg");
+                throw new IOException("请求失败,错误信息: " + errMsg);
+            }
+
+            // 获取 data 字段
+            Map<String, Object> dataMap = (Map<String, Object>) responseMap.get("data");
+
+            // 获取 videoUrl 字段
+            return (String) dataMap.get("videoUrl");
+        } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
+            throw new IOException("SSL 配置出错", e);
+        }
+    }
+
+    private static CloseableHttpClient createHttpClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
+        SSLContext sslContext = new SSLContextBuilder()
+                .loadTrustMaterial(null, (chain, authType) -> true).build();
+
+        SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
+                sslContext,
+                NoopHostnameVerifier.INSTANCE
+        );
+
+        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
+                .register("http", PlainConnectionSocketFactory.getSocketFactory())
+                .register("https", sslSocketFactory)
+                .build();
+
+        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
+        return HttpClients.custom()
+                .setSSLSocketFactory(sslSocketFactory)
+                .setConnectionManager(cm)
+                .build();
+    }
+
+
+    public static byte[] downloadVideo(String videoUrl) throws IOException {
+        HttpClient httpClient = HttpClients.createDefault();
+        HttpGet httpGet = new HttpGet(URI.create(videoUrl));
+        HttpResponse response = httpClient.execute(httpGet);
+        return EntityUtils.toByteArray(response.getEntity());
+    }
+}