Browse Source

获取报警回放接口开发

gao.qiang 2 năm trước cách đây
mục cha
commit
2a3de6297f

+ 59 - 8
vehicle-admin/src/main/java/com/ozs/web/controller/sdk/GeoHazardMonitorTokenController.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.ozs.common.core.domain.AjaxResult;
+import com.ozs.common.core.redis.RedisCache;
 import com.ozs.common.exception.base.BaseException;
 import com.ozs.common.utils.ApiTokenUtils;
 import com.ozs.common.utils.ChineseToPingyin;
@@ -41,6 +42,7 @@ import com.ozs.entity.vo.RespGeoHazardMonitorVo;
 import com.ozs.entity.vo.RespHeartbeatVo;
 import com.ozs.entity.vo.RespMsgAlarmVo;
 import com.ozs.entity.vo.TerminalIgnoreVo;
+import com.ozs.framework.config.ServerConfig;
 import com.ozs.service.BaseCameraManagementService;
 import com.ozs.service.BaseDeviceDynamicManagementService;
 import com.ozs.service.BaseRailwayManagementService;
@@ -73,6 +75,7 @@ import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.TimeUnit;
 
 /**
  * 1. 获取身份认证控制层
@@ -113,6 +116,10 @@ public class GeoHazardMonitorTokenController {
     private IgnoreUtils ignoreUtils;
     @Autowired
     private BaseRailwayManagementService baseRailwayManagementService;
+    @Autowired
+    private RedisCache redisCache;
+    @Autowired
+    private ServerConfig serverConfig;
 
     /**
      * 获取web访问令牌
@@ -759,9 +766,15 @@ public class GeoHazardMonitorTokenController {
         }
     }
 
+    /**
+     * 获取报警回放
+     * @param parameter
+     * @param request
+     * @return
+     */
     @PostMapping("/api/alarm/play")
     public String alarmPlay(@RequestParam("parameter") String parameter, HttpServletRequest request) {
-        Map<String,Object> map=new HashMap<>();
+        Map<String, Object> map = new HashMap<>();
         String token = apiTokenUtils.getGeoHazardMonitorToken(request);
         log.info("token:{}", token);
         log.info("parameter:{}", parameter);
@@ -772,18 +785,56 @@ public class GeoHazardMonitorTokenController {
             LambdaQueryWrapper<MsgAlarm> wrapper = new LambdaQueryWrapper<>();
             wrapper.eq(MsgAlarm::getAlarmId, terminalIgnoreVo.getAlarmId());
             MsgAlarm one = msgAlarmService.getOne(wrapper);
-            if (ObjectUtils.isEmpty(one)){
+            ArrayList<String> urls = new ArrayList<>();
+            if (ObjectUtils.isEmpty(one)) {
                 jsonObject.put("resultCode", 0);
                 jsonObject.put("message", "失败");
                 jsonObject.put("data", "没有该报警唯一UUID的报警数据");
                 return SM4Utils.encryptData_ECB(JSONObject.toJSONString(jsonObject), "4370780c9a8c43e5");
+            } else {
+                //获取报警里程所监控的所有相机
+                LambdaQueryWrapper<BaseCameraManagement> camera = new LambdaQueryWrapper<BaseCameraManagement>();
+                camera.ge(BaseCameraManagement::getBeginMile, one.getAlarmMile());
+                camera.le(BaseCameraManagement::getEndMile, one.getAlarmMile());
+                camera.eq(BaseCameraManagement::getLineDir, one.getLineDir());
+                camera.orderByAsc(BaseCameraManagement::getInstallMile);
+                List<BaseCameraManagement> baseCameraManagementList = baseCameraManagementService.list(camera);
+                if (baseCameraManagementList.size() > 0) {
+                    for (BaseCameraManagement baseCameraManagement : baseCameraManagementList) {
+                        Object cacheObject = redisCache.getCacheObject("STREAMING_ALARM_VIDEO:" + baseCameraManagement.getCameraCode());
+                        if (ObjectUtils.isEmpty(cacheObject)) {
+                            String url = null;
+                            if ("1".equals(one.getIsRelease().toString())) {
+                                url = CameraUtil.historyPlayListStr(baseCameraManagement.getChannel(),
+                                        one.getAlarmTime(),
+                                        one.getReleasedTime(),
+                                        true);
+                                redisCache.setCacheObject("STREAMING_ALARM_VIDEO:" + baseCameraManagement.getCameraCode(), url);
+                                redisCache.expire("STREAMING_ALARM_VIDEO:" + baseCameraManagement.getCameraCode(), 365L, TimeUnit.DAYS);
+                            } else {
+                                url = CameraUtil.historyPlayListStr(baseCameraManagement.getChannel(),
+                                        one.getAlarmTime(),
+                                        new Date(),
+                                        false);
+                            }
+                            urls.add(serverConfig.getUrl() + url);
+                        }else{
+                            urls.add(serverConfig.getUrl() + cacheObject);
+                        }
+                    }
+                } else {
+                    jsonObject.put("resultCode", 1);
+                    jsonObject.put("message", "失败");
+                    jsonObject.put("data", "没有该报警里程位置的相机");
+                    return SM4Utils.encryptData_ECB(JSONObject.toJSONString(jsonObject), "4370780c9a8c43e5");
+                }
+                String[] array = urls.toArray(new String[]{});
+                map.put("urls", array);
+                jsonObject.put("resultCode", 1);
+                jsonObject.put("message", "ok");
+                jsonObject.put("data", map);
+                return SM4Utils.encryptData_ECB(JSONObject.toJSONString(jsonObject), "4370780c9a8c43e5");
             }
-            //todo 报警视频未写
-            map.put("url","");
-            jsonObject.put("resultCode", 1);
-            jsonObject.put("message", "ok");
-            jsonObject.put("data", map);
-            return SM4Utils.encryptData_ECB(JSONObject.toJSONString(jsonObject), "4370780c9a8c43e5");
         } else {
             jsonObject.put("resultCode", 2);
             jsonObject.put("message", "失败");

+ 83 - 17
vehicle-admin/src/main/java/com/ozs/web/core/util/CameraUtil.java

@@ -5,6 +5,7 @@ import com.alibaba.fastjson2.JSONObject;
 import com.ozs.common.config.BaseConfig;
 import com.ozs.common.constant.Constants;
 import com.ozs.common.core.domain.entity.SysDictData;
+import com.ozs.common.core.redis.RedisCache;
 import com.ozs.common.exception.base.BaseException;
 import com.ozs.common.utils.DateUtils;
 import com.ozs.common.utils.HttpClientUtil;
@@ -14,6 +15,7 @@ import com.ozs.entity.MsgAlarm;
 import com.ozs.service.BaseCameraManagementService;
 import com.ozs.system.mapper.SysDictDataMapper;
 import com.ozs.web.core.config.CaneraConfig;
+import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -37,6 +39,7 @@ import java.util.stream.Collectors;
 @Configuration
 @Slf4j
 public class CameraUtil {
+    private static final ExecutorService executor = Executors.newFixedThreadPool(20);
 
     private static String historyUrl;
     private static String ffmpegPath;
@@ -56,6 +59,11 @@ public class CameraUtil {
     private SysDictDataMapper dictDataMapper;
     @Resource
     BaseCameraManagementService baseCameraManagementService;
+    private static RedisCache rc;
+    @Autowired
+    private RedisCache redisCache;
+
+    public final static String tsFilekey = "mergeVideoTsFile";
 
 
     /**
@@ -66,7 +74,7 @@ public class CameraUtil {
      * @return
      * @throws IOException
      */
-    public static String historyPlay(List<String> fromVideoFileList, String ph, String uuid) {
+    public static String historyPlay(List<String> fromVideoFileList, String ph, boolean flay) {
         // 视频服务映射路径
         String NewfilePath = BaseConfig.getProfile() + "/" + ph;
         log.info("NewfilePath:{}", NewfilePath);
@@ -74,32 +82,89 @@ public class CameraUtil {
         if (ObjectUtils.isEmpty(fromVideoFileList) || fromVideoFileList.size() <= 0) {
             throw new BaseException("当前相机无视频录像");
         }
-        ExecutorService executor = Executors.newFixedThreadPool(10);
-
         executor.submit(new Runnable() {
             @Override
             public void run() {
                 try {
-                    Map<String, String> map = myConvetor(fromVideoFileList, NewfilePath, uuid);
-                    if (!ObjectUtils.isEmpty(map)) {
-                        cUtil.cmd(map.get("cmd"));
-                        //删除生成的ts文件
-                        File file1 = new File(map.get("path"));
-                        if (file1.exists()) {
-                            file1.delete();
-                        }
-                    }
+                    txConvetor(fromVideoFileList, NewfilePath, flay);
                 } catch (IOException e) {
                     log.error(e.getMessage());
                     e.printStackTrace();
                 }
             }
         });
-        executor.shutdown();
+//        executor.shutdown();
 
         return Constants.RESOURCE_PREFIX + "/" + ph;
     }
 
+
+    @SneakyThrows
+    public static void txConvetor(List<String> fromVideoFileList,
+                                  String newfilePath,
+                                  boolean fly) throws IOException {
+        /*
+        * ffmpeg -i 20230411_155847_155947-d4c2265d-d83e-11ed-8e7f-fa163e4e1e9f.flv -c:v copy 1.ts
+ffmpeg -i 20230411_155948_160048-f91fea03-d83e-11ed-8e7f-fa163e4e1e9f.flv -c:v copy 2.ts
+ffmpeg -i "concat:1.ts|2.ts" -c copy output.mp4
+        * */
+
+        File file = new File(newfilePath);
+        boolean flay = false;
+        if (!file.getParentFile().exists()) {
+            boolean mkdirs = file.getParentFile().mkdirs();
+            log.info("创建文件夹:{}", file.getParentFile().getPath());
+            log.info("创建文件夹结果:{}", mkdirs);
+            flay = true;
+        }
+        cUtil.cmd("chomd -R 777 " + file.getParentFile().getPath());
+        log.info("newfilePath:{}", newfilePath);
+        StringBuffer sm = new StringBuffer(ffmpegPath + " -i \"concat:");
+        List<String> fileTs = new ArrayList<>();
+        for (int t = 0; t < fromVideoFileList.size(); t++) {
+            File ft = new File(fromVideoFileList.get(t));
+            if (ft.exists()) {
+                log.info("file:{}", fromVideoFileList.get(t));
+                String substring = fromVideoFileList.get(t).substring(0, fromVideoFileList.get(t).lastIndexOf("."));
+                int x;//定义两变量
+                Random ne = new Random();//实例化一个random的对象ne
+                x = ne.nextInt(9999 - 1000 + 1) + 1000;//为变量赋随机值1000-9999
+                substring = substring + x;//定义两变量
+
+                String cmdstr = ffmpegPath + " -i " + fromVideoFileList.get(t) + " -c:v copy " + substring + ".ts";
+                log.info("转换命令:{}", cmdstr);
+                cUtil.cmd(cmdstr);
+                fileTs.add(substring + ".ts");
+                if (t != fromVideoFileList.size() - 1) {
+                    sm.append(substring + ".ts|");
+                } else {
+                    sm.append(substring + ".ts\" ");
+                }
+            }
+        }
+
+        if (fileTs.size() > 0) {
+            Map<String, Object> mergeVideoTsFile = rc.getCacheMap(tsFilekey);
+            if (ObjectUtils.isEmpty(mergeVideoTsFile)) {
+                mergeVideoTsFile = new HashMap<>();
+            }
+            if (!flay) {
+                // 如果没有解除,把生成的文件放入要删除的定时任务 redis key 中
+                fileTs.add(newfilePath);
+            }
+            mergeVideoTsFile.put(new Date().getTime() + "", fileTs);
+            rc.deleteObject(tsFilekey);
+            if (mergeVideoTsFile.size() > 0) {
+                rc.setCacheMap(tsFilekey, mergeVideoTsFile);
+            }
+
+            sm.append("-c copy " + newfilePath);
+            log.info("合并命令:{}", sm.toString());
+            cUtil.cmd(sm.toString());
+        }
+
+    }
+    
     /**
      * 实时播放的拼接流
      *
@@ -169,15 +234,15 @@ public class CameraUtil {
      * @param endTm   结束时间
      * @return
      */
-    public static String historyPlayListStr(String channel, Date startTm, Date endTm) {
+    public static String historyPlayListStr(String channel, Date startTm, Date endTm, boolean flay) {
         List<String> list = filterPlayList(channel, startTm, endTm, filePath);
         String uuid = UUID.randomUUID().toString();
-        String ph = "flv/" + DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, new Date())
+        String ph = "record/flv/" + DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, new Date())
                 + "/" + channel + "/"
-                + uuid + ".flv";
+                + uuid + ".mp4";
         if (!ObjectUtils.isEmpty(list)) {
             try {
-                return historyPlay(list, ph, uuid);
+                return historyPlay(list, ph, flay);
             } catch (Exception e) {
                 log.error(e.getMessage());
                 e.printStackTrace();
@@ -376,6 +441,7 @@ public class CameraUtil {
         transcribeFilePath = caneraConfig.getTranscribeFilePath();
         webUrl = caneraConfig.getWebUrl();
         bakUrl = caneraConfig.getBakUrl();
+        rc = redisCache;
         cUtil = cmdCameraUtil;
     }