|
@@ -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;
|
|
|
}
|
|
|
|