|
@@ -0,0 +1,990 @@
|
|
|
+package com.ozs.utils;
|
|
|
+
|
|
|
+import com.alibaba.fastjson2.JSON;
|
|
|
+import com.alibaba.fastjson2.JSONObject;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+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;
|
|
|
+import com.ozs.common.utils.http.HttpUtils;
|
|
|
+import com.ozs.entity.BaseTerminal;
|
|
|
+import com.ozs.entity.MsgHeartbeatAlarmMessage;
|
|
|
+import com.ozs.entity.vo.CamerasVo;
|
|
|
+import com.ozs.entity.vo.PlaybackVo;
|
|
|
+import com.ozs.framework.config.ServerConfig;
|
|
|
+import com.ozs.service.BaseTerminalService;
|
|
|
+import com.ozs.service.MsgHeartbeatAlarmMessageService;
|
|
|
+import com.ozs.system.mapper.SysDictDataMapper;
|
|
|
+import com.ozs.system.service.ISysDictTypeService;
|
|
|
+import lombok.SneakyThrows;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.context.annotation.Configuration;
|
|
|
+import org.springframework.util.ObjectUtils;
|
|
|
+
|
|
|
+import javax.annotation.PostConstruct;
|
|
|
+import java.io.BufferedReader;
|
|
|
+import java.io.BufferedWriter;
|
|
|
+import java.io.File;
|
|
|
+import java.io.FileFilter;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.InputStreamReader;
|
|
|
+import java.io.OutputStreamWriter;
|
|
|
+import java.io.PrintWriter;
|
|
|
+import java.text.ParseException;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Calendar;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.GregorianCalendar;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Random;
|
|
|
+import java.util.Set;
|
|
|
+import java.util.UUID;
|
|
|
+import java.util.concurrent.Callable;
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
|
+import java.util.concurrent.ExecutionException;
|
|
|
+import java.util.concurrent.ExecutorService;
|
|
|
+import java.util.concurrent.Executors;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.concurrent.TimeoutException;
|
|
|
+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;
|
|
|
+ private static String filePath;
|
|
|
+ private static String transcribeFilePath;
|
|
|
+ private static String webUrl;
|
|
|
+ private static String bakUrl;
|
|
|
+ private static String bakUrlRtsp;
|
|
|
+ private static String wsUrl;
|
|
|
+ private static CmdCameraUtil cUtil;
|
|
|
+ private static RedisCache rc;
|
|
|
+ private static ServerConfig sc;
|
|
|
+ private static String recordUrl;
|
|
|
+ private static String hkUrl;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private CaneraConfig caneraConfig;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private CmdCameraUtil cmdCameraUtil;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private SysDictDataMapper dictDataMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private RedisCache redisCache;
|
|
|
+ @Autowired
|
|
|
+ private ServerConfig serverConfig;
|
|
|
+ @Autowired
|
|
|
+ private BaseTerminalService baseTerminalService;
|
|
|
+ @Autowired
|
|
|
+ private MsgHeartbeatAlarmMessageService msgHeartbeatAlarmMessageService;
|
|
|
+ @Autowired
|
|
|
+ private ISysDictTypeService dictTypeService;
|
|
|
+
|
|
|
+ public final static String tsFilekey = "mergeVideoTsFile";
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 历史回放
|
|
|
+ *
|
|
|
+ * @param fromVideoFileList
|
|
|
+ * @param ph
|
|
|
+ * @return
|
|
|
+ * @throws IOException
|
|
|
+ */
|
|
|
+ public static String historyPlay(List<String> fromVideoFileList, String ph, boolean flay) {
|
|
|
+ // 视频服务映射路径
|
|
|
+ String NewfilePath = BaseConfig.getProfile() + "/" + ph;
|
|
|
+ log.info("NewfilePath:{}", NewfilePath);
|
|
|
+ log.info("fromVideoFileList:{}", fromVideoFileList);
|
|
|
+ if (ObjectUtils.isEmpty(fromVideoFileList) || fromVideoFileList.size() <= 0) {
|
|
|
+ throw new BaseException("当前相机无视频录像");
|
|
|
+ }
|
|
|
+ executor.submit(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ try {
|
|
|
+ txConvetor(fromVideoFileList, NewfilePath, flay);
|
|
|
+ } catch (IOException e) {
|
|
|
+ log.error(e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+// 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(System.currentTimeMillis() + "", 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());
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 实时播放的拼接流
|
|
|
+ *
|
|
|
+ * @param cameraCode 相机编码
|
|
|
+ * @param channel 相机通道
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static String getPlayFlv(String cameraCode, String channel, boolean flay) {
|
|
|
+ if (!flay) {
|
|
|
+ return bakUrl + "/hdl/" + channel + "/" + cameraCode + ".flv";
|
|
|
+ }
|
|
|
+ return webUrl + "/hdl/" + channel + "/" + cameraCode + ".flv";
|
|
|
+
|
|
|
+
|
|
|
+// if (!flay) {
|
|
|
+// return bakUrl + "/ws/" + channel + "/" + cameraCode + ".flv";
|
|
|
+// }
|
|
|
+// return webUrl + "/ws/" + channel + "/" + cameraCode + ".flv";
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Rtsp实时播放的拼接流
|
|
|
+ *
|
|
|
+ * @param cameraCode 相机编码
|
|
|
+ * @param channel 相机通道
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static String getPlayFlvRtsp(String cameraCode, String channel, boolean flay) {
|
|
|
+ if (!flay) {
|
|
|
+ return bakUrlRtsp + "/" + channel + "/" + cameraCode;
|
|
|
+ }
|
|
|
+ return bakUrlRtsp + "/" + channel + "/" + cameraCode;
|
|
|
+
|
|
|
+
|
|
|
+// if (!flay) {
|
|
|
+// return bakUrl + "/ws/" + channel + "/" + cameraCode + ".flv";
|
|
|
+// }
|
|
|
+// return webUrl + "/ws/" + channel + "/" + cameraCode + ".flv";
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String getPlayFlv(String cameraCode, String channel) {
|
|
|
+ return getPlayFlv(cameraCode, channel, true);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String invite(String cameraCode, String channel) {
|
|
|
+ String result = null;
|
|
|
+ String url = bakUrl + "/api/gb28181/invite?id=" + cameraCode + "&channel=" + channel;
|
|
|
+ try {
|
|
|
+ result = HttpClientUtil.get(url);
|
|
|
+ log.info("result:{}", result);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.info(e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 开启录制功能
|
|
|
+ *
|
|
|
+ * @param cameraCode 相机编码
|
|
|
+ * @param channel 相机通道
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static String startRecording(String cameraCode, String channel) {
|
|
|
+ return historyUrl + "/recordpro/api/start?streamPath=" + channel + "/" + cameraCode;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 关闭录制功能
|
|
|
+ *
|
|
|
+ * @param taskId 录像接口返回的任务ID
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static String endRecording(String taskId) {
|
|
|
+ return historyUrl + "/recordpro/api/stop?id=" + taskId;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 历史回放流(获取)
|
|
|
+ *
|
|
|
+ * @param channel 相机通道
|
|
|
+ * @param startTm 开始时间
|
|
|
+ * @param endTm 结束时间
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ 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 = "record/flv/" + DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, new Date())
|
|
|
+ + "/" + channel + "/"
|
|
|
+ + uuid + ".mp4";
|
|
|
+ if (!ObjectUtils.isEmpty(list)) {
|
|
|
+ try {
|
|
|
+ return historyPlay(list, ph, flay);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ throw new BaseException("当前相机无视频录像");
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 过滤符合条件的视频
|
|
|
+ *
|
|
|
+ * @param channel
|
|
|
+ * @param startTm
|
|
|
+ * @param endTm
|
|
|
+ * @param mappingUrl
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static List<String> filterPlayList(String channel, Date startTm, Date endTm, String mappingUrl) {
|
|
|
+ if (StringUtils.isBlank(channel)
|
|
|
+ || ObjectUtils.isEmpty(startTm)
|
|
|
+ || ObjectUtils.isEmpty(endTm)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<String> ls = new ArrayList<>();
|
|
|
+ Map<Date, String> m = new HashMap<>();
|
|
|
+ // 调用视频服务返回参数
|
|
|
+ String startTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, startTm);
|
|
|
+ String endTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, endTm);
|
|
|
+
|
|
|
+ String param = "channel=" + channel + "&startTime=" + startTime + "&endTime=" + endTime;
|
|
|
+ String s = HttpUtils.sendGet(historyUrl + "/api/record/flv/list", param);
|
|
|
+ // 视频拼接
|
|
|
+ if (!StringUtils.isBlank(s) && !"null".equals(s) && !s.startsWith("<!DOCTYPE html>")) {
|
|
|
+ List<Map<String, Object>> maps = JSON.parseArray(s, Map.class);
|
|
|
+ if (ObjectUtils.isEmpty(maps)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ for (Map<String, Object> map : maps) {
|
|
|
+ Object path = map.get("Path");
|
|
|
+ if (!ObjectUtils.isEmpty(path)) {
|
|
|
+ String s1 = path.toString();
|
|
|
+ String substring = s1.substring(s1.lastIndexOf("/") + 1, s1.length());
|
|
|
+ String substring1 = substring.substring(0, substring.indexOf("-"));
|
|
|
+ String[] s2 = substring1.split("_");
|
|
|
+ if (!ObjectUtils.isEmpty(s2)) {
|
|
|
+
|
|
|
+ String s3 = s2[0] + s2[1];
|
|
|
+ String s4 = s2[0] + s2[2];
|
|
|
+ Date sdate = DateUtils.dateTime(DateUtils.YYYYMMDDHHMMSS, s3);
|
|
|
+ if (s2[1].startsWith("23") && s2[2].startsWith("00")) {
|
|
|
+ sdate = DateUtils.addDays(sdate, -1);
|
|
|
+ }
|
|
|
+ Date edate = DateUtils.dateTime(DateUtils.YYYYMMDDHHMMSS, s4);
|
|
|
+ /* sdate |startTm| edate |endTm| */
|
|
|
+ if (startTm.compareTo(sdate) >= 0
|
|
|
+ && startTm.compareTo(edate) <= 0
|
|
|
+ && endTm.compareTo(edate) >= 0) {
|
|
|
+ m.put(sdate, mappingUrl + path.toString());
|
|
|
+ /* |startTm| sdate edate |endTm| */
|
|
|
+ } else if (startTm.compareTo(sdate) <= 0 && endTm.compareTo(edate) >= 0) {
|
|
|
+ m.put(sdate, mappingUrl + path.toString());
|
|
|
+
|
|
|
+ /* |startTm| sdate |endTm| edate */
|
|
|
+ } else if (startTm.compareTo(sdate) <= 0
|
|
|
+ && endTm.compareTo(sdate) >= 0
|
|
|
+ && endTm.compareTo(edate) <= 0) {
|
|
|
+ m.put(sdate, mappingUrl + path.toString());
|
|
|
+
|
|
|
+ /* sdate |startTm| |endTm| edate */
|
|
|
+ } else if (startTm.compareTo(sdate) >= 0 && endTm.compareTo(edate) <= 0) {
|
|
|
+ m.put(sdate, mappingUrl + path.toString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!ObjectUtils.isEmpty(m) && m.size() > 0) {
|
|
|
+ Set<Date> dates = m.keySet();
|
|
|
+ // 排序
|
|
|
+ dates.stream().parallel().collect(Collectors.toList()).stream().sorted().forEach(d -> {
|
|
|
+ ls.add(m.get(d));
|
|
|
+ });
|
|
|
+ return ls;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 合并视频(转化文件)
|
|
|
+ *
|
|
|
+ * @param fromVideoFileList 视频路径
|
|
|
+ * @param newfilePath 生产新的视频文件路径
|
|
|
+ * @throws IOException
|
|
|
+ */
|
|
|
+ public static Map<String, String> myConvetor(List<String> fromVideoFileList,
|
|
|
+ String newfilePath,
|
|
|
+ String uuid) throws IOException {
|
|
|
+ /*
|
|
|
+ * for f in *.flv; do echo "file '$f'" >> mylist.txt; done
|
|
|
+ ffmpeg -f concat -i mylist.txt -c copy output.flv
|
|
|
+ * */
|
|
|
+
|
|
|
+ File file = new File(newfilePath);
|
|
|
+ boolean flay = false;
|
|
|
+ if (!file.getParentFile().exists()) {
|
|
|
+ file.getParentFile().mkdirs();
|
|
|
+ log.info("创建文件夹:{}", file.getParentFile().getPath());
|
|
|
+ flay = true;
|
|
|
+ }
|
|
|
+ log.info("newfilePath:{}", newfilePath);
|
|
|
+
|
|
|
+
|
|
|
+ StringBuffer sm = new StringBuffer("for f in ");
|
|
|
+ String pathStr = null;
|
|
|
+ for (int t = 0; t < fromVideoFileList.size(); t++) {
|
|
|
+ File ft = new File(fromVideoFileList.get(t));
|
|
|
+ if (ft.exists()) {
|
|
|
+ if (t != fromVideoFileList.size() - 1) {
|
|
|
+// sm.append(fromVideoFileList.get(t) + " ");
|
|
|
+ sm.append(fromVideoFileList.get(t).substring(fromVideoFileList.get(t).lastIndexOf("/") + 1, fromVideoFileList.get(t).length()) + " ");
|
|
|
+ } else {
|
|
|
+// sm.append(fromVideoFileList.get(t));
|
|
|
+ sm.append(fromVideoFileList.get(t).substring(fromVideoFileList.get(t).lastIndexOf("/") + 1, fromVideoFileList.get(t).length()));
|
|
|
+ pathStr = fromVideoFileList.get(t).substring(0, fromVideoFileList.get(t).lastIndexOf("/"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+// String substring = newfilePath.substring(0, newfilePath.lastIndexOf("."));
|
|
|
+// substring = substring + ".txt";
|
|
|
+
|
|
|
+ String substring = uuid + ".txt";
|
|
|
+ log.info("临时转化的文件:{}", substring);
|
|
|
+
|
|
|
+
|
|
|
+ sm.append("; do echo \"file '$f'\" >> " + substring + "; done");
|
|
|
+ String commit = sm.toString();
|
|
|
+ log.info("合并转化文件的命令:{}", commit);
|
|
|
+ Process proc = Runtime.getRuntime().exec("/bin/bash", null, null);
|
|
|
+ BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
|
|
|
+ PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
|
|
|
+
|
|
|
+ try {
|
|
|
+ String commit1 = ffmpegPath + " -f concat -safe 0 -i " + pathStr + "/" + substring + " -c copy " + newfilePath;
|
|
|
+
|
|
|
+ log.info("合并视频命令:{}", commit1);
|
|
|
+ List<String> commands = new ArrayList<>();
|
|
|
+ if (flay) {
|
|
|
+ commands.add("chomd -R 777 " + file.getParentFile().getPath());
|
|
|
+ }
|
|
|
+ //
|
|
|
+ commands.add("cd " + pathStr);
|
|
|
+ // 合并成一个临时文件
|
|
|
+ commands.add(commit);
|
|
|
+
|
|
|
+ // 临时文件转化为 flv
|
|
|
+// commands.add(commit1);
|
|
|
+ log.info("录像视频命令:{}", commands);
|
|
|
+ for (String line : commands) {
|
|
|
+ log.info("命令:{}", line);
|
|
|
+ out.println(line);
|
|
|
+ }
|
|
|
+ out.println("exit");// 这个命令必须执行,否则in流不结束。
|
|
|
+ log.info("命令:{}", "exit");
|
|
|
+ String rspLine = "";
|
|
|
+ while ((rspLine = in.readLine()) != null) {
|
|
|
+ log.info("*****:{}", rspLine);
|
|
|
+ }
|
|
|
+ proc.waitFor();
|
|
|
+ Map<String, String> map = new HashMap<>();
|
|
|
+ map.put("cmd", commit1);
|
|
|
+ map.put("path", pathStr + "/" + substring);
|
|
|
+ return map;
|
|
|
+
|
|
|
+
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ log.error(e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ } finally {
|
|
|
+ in.close();
|
|
|
+ out.close();
|
|
|
+ proc.destroy();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @PostConstruct
|
|
|
+ public void init() {
|
|
|
+ historyUrl = caneraConfig.getHistoryUrl();
|
|
|
+ ffmpegPath = caneraConfig.getFfmpegPath();
|
|
|
+ filePath = caneraConfig.getFilePath();
|
|
|
+ transcribeFilePath = caneraConfig.getTranscribeFilePath();
|
|
|
+ webUrl = caneraConfig.getWebUrl();
|
|
|
+ bakUrl = caneraConfig.getBakUrl();
|
|
|
+ bakUrlRtsp = caneraConfig.getBakUrlRtsp();
|
|
|
+ rc = redisCache;
|
|
|
+ cUtil = cmdCameraUtil;
|
|
|
+ sc = serverConfig;
|
|
|
+ wsUrl = caneraConfig.getWsUrl();
|
|
|
+ recordUrl = caneraConfig.getRecordUrl();
|
|
|
+ hkUrl = caneraConfig.getHkUrl();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 定时任务参数flv文件
|
|
|
+ *
|
|
|
+ * @throws IOException
|
|
|
+ * @throws InterruptedException
|
|
|
+ */
|
|
|
+ public void deleteFlv() throws IOException, InterruptedException {
|
|
|
+ SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
|
|
|
+ Date date = new Date();
|
|
|
+ Calendar calendar = new GregorianCalendar();
|
|
|
+ calendar.setTime(date);
|
|
|
+ calendar.add(calendar.DATE, -1); //把日期往后增加一天,整数 往后推,负数往前移动
|
|
|
+ date = calendar.getTime(); //这个时间就是日期往后推一天的结果
|
|
|
+ String path = BaseConfig.getProfile() + "/flv/" + DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, date);
|
|
|
+ File file = new File(path);
|
|
|
+ if (file.exists()) {
|
|
|
+ List<String> rspList = new ArrayList<String>();
|
|
|
+ Process proc = Runtime.getRuntime().exec("/bin/bash", null, null);
|
|
|
+ BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
|
|
|
+ PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
|
|
|
+ String commit = " rm -rf " + path;
|
|
|
+ List<String> commands = new ArrayList<>();
|
|
|
+
|
|
|
+ // 删除
|
|
|
+ commands.add(commit);
|
|
|
+ log.info("删除昨天的录像视频命令:{}", commands);
|
|
|
+ for (String line : commands) {
|
|
|
+ out.println(line);
|
|
|
+ }
|
|
|
+ out.println("exit");// 这个命令必须执行,否则in流不结束。
|
|
|
+ String rspLine = "";
|
|
|
+ while ((rspLine = in.readLine()) != null) {
|
|
|
+ System.out.println(rspLine);
|
|
|
+ rspList.add(rspLine);
|
|
|
+ }
|
|
|
+ int i = proc.waitFor();
|
|
|
+ log.info("执行结果:{}", i);
|
|
|
+
|
|
|
+ in.close();
|
|
|
+ out.close();
|
|
|
+ proc.destroy();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 定时任务:删除超过配置时长的录制视频
|
|
|
+ *
|
|
|
+ * @throws IOException
|
|
|
+ * @throws InterruptedException
|
|
|
+ */
|
|
|
+ public void deleteFlvExceed() throws IOException, InterruptedException, ParseException {
|
|
|
+ //字典中设置的值
|
|
|
+ List<SysDictData> sysCameraRecordTime = dictDataMapper.selectDictDataByType("sys_camera_record_time");
|
|
|
+
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
|
|
|
+ Date date = new Date();
|
|
|
+ Calendar calendar = new GregorianCalendar();
|
|
|
+ calendar.setTime(date);
|
|
|
+ //正数,日期天数加
|
|
|
+ //负数,日期天数减 提前45天
|
|
|
+ if (!ObjectUtils.isEmpty(sysCameraRecordTime)) {
|
|
|
+ String dictValue = sysCameraRecordTime.get(0).getDictValue();
|
|
|
+ calendar.add(Calendar.DAY_OF_YEAR, Integer.parseInt("-" + dictValue));
|
|
|
+ } else {
|
|
|
+ calendar.add(Calendar.DAY_OF_YEAR, -45);
|
|
|
+ }
|
|
|
+ date = calendar.getTime();
|
|
|
+
|
|
|
+ //遍历每个进行视频录制的摄像头
|
|
|
+ File file = new File(transcribeFilePath);
|
|
|
+ log.info("file.Name()======================================" + file.getName());
|
|
|
+ log.info("file.exists()======================================" + file.exists());
|
|
|
+ if (file.exists() && file.isDirectory()) {
|
|
|
+ //获取文件夹中所有的子文件夹和文件
|
|
|
+ File[] files = file.listFiles();
|
|
|
+ if (!ObjectUtils.isEmpty(files) && files.length > 0) {
|
|
|
+ for (File file1 : files) {
|
|
|
+ // file1=/opt/streams/record/flv/34020000001320000167
|
|
|
+ log.info("file1.Name()======================================" + file1.getName());
|
|
|
+ if (file1.exists() && file1.isDirectory()) {
|
|
|
+ //相机文件
|
|
|
+ File[] fs = file1.listFiles();
|
|
|
+ if (!ObjectUtils.isEmpty(fs) && fs.length > 0) {
|
|
|
+ for (File f : fs) {
|
|
|
+ // f=/opt/streams/record/flv/34020000001320000167/20230328_192033_192037-91509173-cd5a-11ed-8a42-fa163e4e1e9f.flv
|
|
|
+ //fName=20230328_192033_192037-91509173-cd5a-11ed-8a42-fa163e4e1e9f.flv
|
|
|
+ String fName = f.getName();
|
|
|
+ log.info("fName======================================" + fName);
|
|
|
+ String[] split = fName.split("_");
|
|
|
+ if (split.length > 0) {
|
|
|
+ //20230328
|
|
|
+ String s = split[0];
|
|
|
+ Date parse = sdf.parse(s);
|
|
|
+ long fTime = parse.getTime();
|
|
|
+ long dateTime = date.getTime();
|
|
|
+ //删除过期文件
|
|
|
+ if (fTime < dateTime) {
|
|
|
+ f.delete();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+// /**
|
|
|
+// * 定时任务:关闭录制视频
|
|
|
+// *
|
|
|
+// * @throws IOException
|
|
|
+// * @throws InterruptedException
|
|
|
+// */
|
|
|
+// public void closeRecording() throws IOException, InterruptedException, ParseException {
|
|
|
+// LambdaQueryWrapper<BaseCameraManagement> wrapper = new LambdaQueryWrapper<>();
|
|
|
+// wrapper.eq(BaseCameraManagement::getStartRecording, 1);
|
|
|
+// wrapper.isNotNull(BaseCameraManagement::getTaskId);
|
|
|
+// List<BaseCameraManagement> list = baseCameraManagementService.list(wrapper);
|
|
|
+// log.info("list======================================" + list);
|
|
|
+// List<String> collect = list.stream().map(BaseCameraManagement::getCameraCode).collect(Collectors.toList());
|
|
|
+//// List<String> collect = new ArrayList<>();
|
|
|
+//// collect.add("42010001541320001116");
|
|
|
+// //遍历每个进行视频录制的摄像头
|
|
|
+// File file = new File(transcribeFilePath);
|
|
|
+// log.info("closeRecording-file.Name()======================================" + file.getName());
|
|
|
+// log.info("closeRecording-file.exists()======================================" + file.exists());
|
|
|
+// if (file.exists() && file.isDirectory()) {
|
|
|
+// //获取文件夹中所有的子文件夹和文件
|
|
|
+// File[] files = file.listFiles();
|
|
|
+// if (!ObjectUtils.isEmpty(files) && files.length > 0) {
|
|
|
+// for (File file1 : files) {
|
|
|
+// log.info("closeRecording-file1---------------" + file1);
|
|
|
+// log.info("closeRecording-cameraCode---------------" + collect);
|
|
|
+// String substring = file1.toString().substring(file1.toString().lastIndexOf("\\") + 1);
|
|
|
+// if (collect.contains(substring)) {
|
|
|
+// File[] files1 = CameraUtil.getCurFilesList(file1.toString());
|
|
|
+// if (!ObjectUtils.isEmpty(files1) && files1.length > 0) {
|
|
|
+// int length = files1.length;
|
|
|
+// File file2 = files1[length - 1];
|
|
|
+// log.info("closeRecording-file2---------------" + file2);
|
|
|
+// String time = file2.toString().substring(file2.toString().lastIndexOf("\\") + 1);
|
|
|
+// String substring1 = time.substring(0, 15);
|
|
|
+// String substring2 = substring1.substring(0, 4);
|
|
|
+// String substring3 = substring1.substring(4, 6);
|
|
|
+// String substring4 = substring1.substring(6, 8);
|
|
|
+// String substring5 = substring1.substring(9, 11);
|
|
|
+// String substring6 = substring1.substring(11, 13);
|
|
|
+// String substring7 = substring1.substring(13, 15);
|
|
|
+// String date = substring2 + "-" + substring3 + "-" + substring4 + " " + substring5 + ":" + substring6 + ":" + substring7;
|
|
|
+// System.out.println(date);
|
|
|
+// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
+// Date parse = sdf.parse(date);
|
|
|
+// //当前时间戳
|
|
|
+// long dades = System.currentTimeMillis();
|
|
|
+// //文件的时间戳
|
|
|
+// long time1 = parse.getTime();
|
|
|
+// //当前时间10分钟之前的时间戳
|
|
|
+// long time2 = dades - 600000L;
|
|
|
+// if (time2 <= time1 && time1 < dades) {
|
|
|
+// } else {
|
|
|
+// LambdaQueryWrapper<BaseCameraManagement> lw = new LambdaQueryWrapper<BaseCameraManagement>();
|
|
|
+// lw.eq(BaseCameraManagement::getCameraCode, substring);
|
|
|
+// BaseCameraManagement baseCameraManagement = baseCameraManagementService.getOne(lw);
|
|
|
+// log.info("closeRecording-endRecording------------" + baseCameraManagement.getTaskId());
|
|
|
+// String start = HttpUtils.sendGet(CameraUtil.endRecording(baseCameraManagement.getTaskId()));
|
|
|
+// log.info("closeRecording-endRecording------------" + start);
|
|
|
+// if ("success".equals(start)) {
|
|
|
+// baseCameraManagement.setStartRecording(2);
|
|
|
+// baseCameraManagement.setTaskId("");
|
|
|
+// } else {
|
|
|
+// baseCameraManagement.setStartRecording(2);
|
|
|
+// baseCameraManagement.setTaskId("");
|
|
|
+// log.error("关闭视频录制异常日志如下:" + start);
|
|
|
+// }
|
|
|
+// baseCameraManagementService.updateById(baseCameraManagement);
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+
|
|
|
+ public static File[] getCurFilesList(String filePath) {
|
|
|
+ File path = new File(filePath);
|
|
|
+ File[] listFiles = path.listFiles(new FileFilter() {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean accept(File pathname) {
|
|
|
+ if (pathname.isFile()) {
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ return listFiles;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void execute(String command) {
|
|
|
+ try {
|
|
|
+ ProcessBuilder process = new ProcessBuilder(command);
|
|
|
+ process.inheritIO().start().waitFor();
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public static List<Map<String, Object>> getRecordList(String channel, Date startTm, Date endTm) {
|
|
|
+ return filterRecordList(channel, startTm, endTm, filePath, recordUrl + "profile/");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * HTTP流转RTSP流
|
|
|
+ */
|
|
|
+ public void streamConversion(String code) {
|
|
|
+
|
|
|
+ ExecutorService executor = Executors.newSingleThreadExecutor();
|
|
|
+ Callable<String> task = new Callable<String>() {
|
|
|
+ @Override
|
|
|
+ public String call() throws Exception {
|
|
|
+ // 执行网络请求...
|
|
|
+ log.info(ffmpegPath + " -re -i /opt/streams/file/vid/" + code + ".mp4 -c:v copy -c:a copy -f flv rtmp://124.70.58.209:1935/live/" + code);
|
|
|
+ cmdCameraUtil.cmd(ffmpegPath + " -re -i /opt/streams/file/vid/" + code + ".mp4 -c:v copy -c:a copy -f flv rtmp://124.70.58.209:1935/live/" + code);
|
|
|
+ return "Response";
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ try {
|
|
|
+ String result = executor.submit(task).get(1, TimeUnit.SECONDS); // 设置5秒超时时间
|
|
|
+ System.out.println("Response: " + result);
|
|
|
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
|
|
|
+ // 请求超时处理逻辑
|
|
|
+ System.out.println("Request timeout");
|
|
|
+ }
|
|
|
+
|
|
|
+ executor.shutdown();
|
|
|
+
|
|
|
+// try {
|
|
|
+// Process proc = Runtime.getRuntime().exec("/bin/bash", null, null);
|
|
|
+// BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
|
|
|
+// PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
|
|
|
+// String commit = ffmpegPath+" -re -i /opt/streams/file/"+code+".mp4 -c:v copy -c:a copy -f rtsp rtsp://124.70.58.209:8554/live/"+code;
|
|
|
+// List<String> commands = new ArrayList<>();
|
|
|
+//
|
|
|
+// // 删除
|
|
|
+// commands.add(commit);
|
|
|
+// log.info("HTTP流转RTSP流:{}", commands);
|
|
|
+// for (String line : commands) {
|
|
|
+// out.println(line);
|
|
|
+// }
|
|
|
+// out.println("exit");// 这个命令必须执行,否则in流不结束。
|
|
|
+// String rspLine = "";
|
|
|
+// while ((rspLine = in.readLine()) != null) {
|
|
|
+// System.out.println(rspLine);
|
|
|
+//
|
|
|
+// }
|
|
|
+// int i = proc.waitFor();
|
|
|
+// log.info("执行结果:{}", i);
|
|
|
+//
|
|
|
+// in.close();
|
|
|
+// out.close();
|
|
|
+// proc.destroy();
|
|
|
+// } catch (IOException e) {
|
|
|
+// log.error(e.getMessage());
|
|
|
+// } catch (InterruptedException e) {
|
|
|
+// e.printStackTrace();
|
|
|
+// }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * RTSP流下载
|
|
|
+ */
|
|
|
+ public static void streamUrlDownload(String url, String code) {
|
|
|
+ log.info(ffmpegPath + " -i " + url + " -c copy /opt/stream/map" + code);
|
|
|
+ cUtil.cmd(ffmpegPath + " -i " + url + " -c copy /opt/stream/map" + code);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public static List<Map<String, Object>> filterRecordList(String channel,
|
|
|
+ Date startTm,
|
|
|
+ Date endTm,
|
|
|
+ String mappingUrl,
|
|
|
+ String wUrl) {
|
|
|
+ List<Map<String, Object>> rmaps = new ArrayList<>();
|
|
|
+
|
|
|
+ if (StringUtils.isBlank(channel)
|
|
|
+ || ObjectUtils.isEmpty(startTm)
|
|
|
+ || ObjectUtils.isEmpty(endTm)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ Map<Date, Map<String, Object>> m = new HashMap<>();
|
|
|
+ // 调用视频服务返回参数
|
|
|
+ String startTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, startTm);
|
|
|
+ String endTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, endTm);
|
|
|
+
|
|
|
+ String param = "channel=" + channel + "&startTime=" + startTime + "&endTime=" + endTime;
|
|
|
+ // /api/record/flv/list
|
|
|
+ String s = HttpUtils.sendGet(webUrl + "/recordpro/api/list", param);
|
|
|
+ // 视频拼接
|
|
|
+ if (!StringUtils.isBlank(s) || "null".equals(s)) {
|
|
|
+ List<Map<String, Object>> maps = JSON.parseArray(s, Map.class);
|
|
|
+ if (ObjectUtils.isEmpty(maps)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ for (Map<String, Object> map : maps) {
|
|
|
+ Object path = map.get("Path");
|
|
|
+ Object size = map.get("Size");
|
|
|
+ Object duration = map.get("Duration");
|
|
|
+ if (!ObjectUtils.isEmpty(path)) {
|
|
|
+ String s1 = path.toString();
|
|
|
+ String substring = s1.substring(s1.lastIndexOf("/") + 1, s1.length());
|
|
|
+ String substring1 = substring.substring(0, substring.indexOf("-"));
|
|
|
+ String[] s2 = substring1.split("_");
|
|
|
+ if (!ObjectUtils.isEmpty(s2)) {
|
|
|
+ Map<String, Object> mo = new HashMap<>();
|
|
|
+
|
|
|
+ String s3 = s2[0] + s2[1];
|
|
|
+ String s4 = s2[0] + s2[2];
|
|
|
+ Date sdate = DateUtils.dateTime(DateUtils.YYYYMMDDHHMMSS, s3);
|
|
|
+ if (s2[1].startsWith("23") && s2[2].startsWith("00")) {
|
|
|
+ sdate = DateUtils.addDays(sdate, -1);
|
|
|
+ }
|
|
|
+ Date edate = DateUtils.dateTime(DateUtils.YYYYMMDDHHMMSS, s4);
|
|
|
+ mo.put("startTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, sdate));
|
|
|
+ mo.put("entTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, edate));
|
|
|
+ mo.put("url", wUrl + path.toString());
|
|
|
+ mo.put("path", mappingUrl + path.toString());
|
|
|
+ mo.put("fileName", substring);
|
|
|
+ mo.put("size", size);
|
|
|
+ mo.put("duration", duration);
|
|
|
+ /* sdate |startTm| edate |endTm| */
|
|
|
+ if (startTm.compareTo(sdate) >= 0
|
|
|
+ && startTm.compareTo(edate) <= 0
|
|
|
+ && endTm.compareTo(edate) >= 0) {
|
|
|
+ m.put(sdate, mo);
|
|
|
+ /* |startTm| sdate edate |endTm| */
|
|
|
+ } else if (startTm.compareTo(sdate) <= 0 && endTm.compareTo(edate) >= 0) {
|
|
|
+ m.put(sdate, mo);
|
|
|
+
|
|
|
+ /* |startTm| sdate |endTm| edate */
|
|
|
+ } else if (startTm.compareTo(sdate) <= 0
|
|
|
+ && endTm.compareTo(sdate) >= 0
|
|
|
+ && endTm.compareTo(edate) <= 0) {
|
|
|
+ m.put(sdate, mo);
|
|
|
+
|
|
|
+ /* sdate |startTm| |endTm| edate */
|
|
|
+ } else if (startTm.compareTo(sdate) >= 0 && endTm.compareTo(edate) <= 0) {
|
|
|
+ m.put(sdate, mo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!ObjectUtils.isEmpty(m) && m.size() > 0) {
|
|
|
+ Set<Date> dates = m.keySet();
|
|
|
+ // 排序
|
|
|
+ dates.stream().parallel().collect(Collectors.toList()).stream().sorted().forEach(d -> {
|
|
|
+
|
|
|
+ rmaps.add(m.get(d));
|
|
|
+ });
|
|
|
+ log.info("rmaps:{}", rmaps);
|
|
|
+ return rmaps;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public void heartbeat() {
|
|
|
+ List<BaseTerminal> list = baseTerminalService.list();
|
|
|
+ for (BaseTerminal baseTerminal : list) {
|
|
|
+ QueryWrapper<MsgHeartbeatAlarmMessage> wrapper = new QueryWrapper<>();
|
|
|
+ wrapper.eq("terminal_code", wrapper);
|
|
|
+ wrapper.orderByDesc("create_time");
|
|
|
+ wrapper.last("limit 1");
|
|
|
+ MsgHeartbeatAlarmMessage msgHeartbeatAlarmMessage = msgHeartbeatAlarmMessageService.getOne(wrapper);
|
|
|
+ if (ObjectUtils.isEmpty(msgHeartbeatAlarmMessage)) {
|
|
|
+ baseTerminal.setStatus(2);
|
|
|
+ baseTerminalService.updateById(baseTerminal);
|
|
|
+ } else {
|
|
|
+ List<SysDictData> heartbeat = dictTypeService.selectDictDataByType("heartbeat");
|
|
|
+ long timeNow = System.currentTimeMillis();
|
|
|
+ long createTime = msgHeartbeatAlarmMessage.getCreateTime().getTime();
|
|
|
+ int times = Integer.parseInt(heartbeat.get(0).getDictValue());
|
|
|
+ long thereHourMillis = 60 * 1000 * 3 * times;
|
|
|
+ long timeNew = timeNow - thereHourMillis;
|
|
|
+ if (timeNew > createTime) {
|
|
|
+ baseTerminal.setStatus(2);
|
|
|
+ baseTerminalService.updateById(baseTerminal);
|
|
|
+ } else {
|
|
|
+ baseTerminal.setStatus(1);
|
|
|
+ baseTerminalService.updateById(baseTerminal);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public void previewURLs(CamerasVo camerasVo) {
|
|
|
+ String result = null;
|
|
|
+ String url = "http://" + hkUrl + "/api/video/v2/cameras/previewURLs";
|
|
|
+ try {
|
|
|
+ result = HttpClientUtil.postJson(url, JSON.toJSONString(camerasVo));
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("previewURLs------------>" + e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ JSONObject outJson = (JSONObject) JSONObject.parse(result);
|
|
|
+ if ("0".equals(outJson.getString("code"))) {
|
|
|
+ log.info("outJson----->" + outJson);
|
|
|
+ JSONObject data = outJson.getJSONObject("data");
|
|
|
+ String urls = data.getString("url");
|
|
|
+ HttpUtils.sendGet(historyUrl + "rtsp/api/pull?target=" + urls + "&streamPath=" + camerasVo.getCameraIndexCode() + "/" + camerasVo.getCameraIndexCode() + "&save=0");
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public void playbackURLs(List<String> list) {
|
|
|
+ CompletableFuture future = CompletableFuture.supplyAsync(() -> {
|
|
|
+ for (String code : list) {
|
|
|
+ PlaybackVo playbackVo = new PlaybackVo();
|
|
|
+ playbackVo.setCameraIndexCode(code);
|
|
|
+ // 获取当前时间
|
|
|
+ LocalDateTime currentTime = LocalDateTime.now();
|
|
|
+ // 获取当前时间的前10分钟时间
|
|
|
+ LocalDateTime beforeTenMinutes = currentTime.minusMinutes(10);
|
|
|
+ // 获取当前时间的后10分钟时间
|
|
|
+ LocalDateTime afterTenMinutes = currentTime.plusMinutes(10);
|
|
|
+ // 格式化时间
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
+ playbackVo.setBeginTime(beforeTenMinutes.format(formatter));
|
|
|
+ playbackVo.setEndTime(afterTenMinutes.format(formatter));
|
|
|
+
|
|
|
+
|
|
|
+ String result = null;
|
|
|
+ String url = "http://" + hkUrl + "/api/video/v2/cameras/playbackURLs";
|
|
|
+ try {
|
|
|
+ result = HttpClientUtil.postJson(url, JSON.toJSONString(playbackVo));
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("playbackURLs------------>" + e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ JSONObject outJson = (JSONObject) JSONObject.parse(result);
|
|
|
+ if ("0".equals(outJson.getString("code"))) {
|
|
|
+ log.info("outJson----->" + outJson);
|
|
|
+ JSONObject data = outJson.getJSONObject("data");
|
|
|
+ String urls = data.getString("url");
|
|
|
+ streamUrlDownload(urls, playbackVo.getCameraIndexCode());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 1;
|
|
|
+ });
|
|
|
+ future.join();
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void main(String[] args) throws InterruptedException, ParseException, IOException {
|
|
|
+// CameraUtil cameraUtil = new CameraUtil();
|
|
|
+// cameraUtil.closeRecording();
|
|
|
+// String s = "/opt/streams/record/flv/42010001541320001116/20230403_235506_000506-22e1523b-d170-11ed-8a42-fa163e4e1e9f.flv";
|
|
|
+// String fileStr = s.substring(s.lastIndexOf("/") + 1, s.length());
|
|
|
+// String pathStr = s.substring(0, s.lastIndexOf("/"));
|
|
|
+// System.out.println(fileStr);
|
|
|
+// System.out.println(pathStr);
|
|
|
+
|
|
|
+ String s = "20230403235512";
|
|
|
+ Date sdate = DateUtils.dateTime(DateUtils.YYYYMMDDHHMMSS, s);
|
|
|
+ sdate = DateUtils.addDays(sdate, -1);
|
|
|
+ System.out.println(DateUtils.parseDateToStr(DateUtils.YYYYMMDDHHMMSS, sdate));
|
|
|
+ }
|
|
|
+}
|