浏览代码

通过命令合成视频

lyhzzz 3 年之前
父节点
当前提交
af676b4d76

+ 1 - 0
src/main/java/com/fdkankan/fusion/common/ResultCode.java

@@ -13,6 +13,7 @@ public enum ResultCode {
     CASE_USE(7010,"案件或场景中使用模型,不能删除"),
     FOLDER_NOT_EXIST(7011,"视频文件夹不存在"),
     CASE_NOT_EXIST(7012,"案件不存在"),
+    MERGER_VIDEO_ERROR(7013,"合成视频失败"),
 
     HOT_ICON_NOT_EXIST(7004,"热点icon不存在");
 

+ 69 - 0
src/main/java/com/fdkankan/fusion/common/util/VideoUtil.java

@@ -1,9 +1,11 @@
 package com.fdkankan.fusion.common.util;
 
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.bytedeco.ffmpeg.avcodec.AVPacket;
 import org.bytedeco.ffmpeg.global.avcodec;
 import org.bytedeco.ffmpeg.global.avutil;
+import org.bytedeco.javacpp.Loader;
 import org.bytedeco.javacv.FFmpegFrameGrabber;
 import org.bytedeco.javacv.FFmpegFrameRecorder;
 import org.bytedeco.javacv.Frame;
@@ -11,6 +13,7 @@ import org.bytedeco.javacv.Frame;
 import java.io.*;
 import java.util.*;
 
+@Slf4j
 public class VideoUtil {
 
     /**
@@ -67,4 +70,70 @@ public class VideoUtil {
         return fileName;
     }
 
+    private volatile static String ffmpeg = Loader.load(org.bytedeco.ffmpeg.ffmpeg.class);
+
+    public static String mergeVideo(LinkedHashSet<String> fromVideoFileList, String newVideoFile) {
+        File tagFile = new File(newVideoFile);
+        if(!tagFile.exists()){
+            tagFile.mkdirs();
+        }
+        String fileName =  UUID.randomUUID().toString().replace("-","")+".mp4";
+        newVideoFile +="/"+fileName;
+        try {
+            List<String> voidTS = new ArrayList<>();
+
+            for (String fromVideoFile : fromVideoFileList) {
+                String format = "%s -y -i %s -vcodec copy -bsf:v h264_mp4toannexb -f mpegts %s";
+                String name = fromVideoFile.substring(0, fromVideoFile.lastIndexOf("."));
+                String command = String.format(format, ffmpeg, fromVideoFile, name + ".ts");
+                execCommand(command);
+                voidTS.add(name + ".ts");
+            }
+            StringBuilder tsPath = new StringBuilder();
+            tsPath.append(ffmpeg);
+            tsPath.append(" -i ");
+            tsPath.append("concat:");
+            for (int t = 0; t < voidTS.size(); t++) {
+                if (t != voidTS.size() - 1) {
+                    tsPath.append(voidTS.get(t) + "|");
+                } else {
+                    tsPath.append(voidTS.get(t));
+                }
+            }
+            tsPath.append(" -vcodec ");
+            tsPath.append(" copy ");
+            tsPath.append(" -bsf:a ");
+            tsPath.append(" aac_adtstoasc ");
+            tsPath.append(" -movflags ");
+            tsPath.append(" +faststart ");
+            tsPath.append(newVideoFile);
+            execCommand(tsPath.toString());
+            //删除生成的ts文件
+            for (String filePath : voidTS) {
+                File file = new File(filePath);
+                file.delete();
+            }
+            return fileName;
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error(" 合并失败-{}", e.getMessage());
+            return null;
+        }
+    }
+
+    private static void execCommand(String command) throws IOException {
+        Process pr = Runtime.getRuntime().exec(command);
+        pr.getOutputStream().close();
+        pr.getInputStream().close();
+        pr.getErrorStream().close();
+        try {
+            pr.waitFor();
+            Thread.sleep(1000);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        } finally {
+            pr.destroy();
+        }
+    }
+
 }

+ 4 - 1
src/main/java/com/fdkankan/fusion/service/impl/CaseVideoServiceImpl.java

@@ -99,7 +99,10 @@ public class CaseVideoServiceImpl extends ServiceImpl<ICaseVideoMapper, CaseVide
         }
         this.saveBatch(videoList);
 
-        String mergeLocalName = VideoUtil.videoMerge(filePathSet, FilePath.VIDEO_LOCAL_PATH);
+        String mergeLocalName = VideoUtil.mergeVideo(filePathSet, FilePath.VIDEO_LOCAL_PATH);
+        if(mergeLocalName == null){
+            throw new BusinessException(ResultCode.MERGER_VIDEO_ERROR);
+        }
         String mergeLocalPath =  FilePath.VIDEO_LOCAL_PATH +"/"+mergeLocalName;
         String ossKey =  String.format(FilePath.VIDEO_OSS_PATH,videoFolder.getVideoFolderId()) +"/"+mergeLocalName;
         uploadToOssUtil.upload(mergeLocalPath,ossKey);