From b53e164ad6a91c346931ae106de56613735241ae Mon Sep 17 00:00:00 2001
From: 康鲁杰 <60095866+KangLujie@users.noreply.github.com>
Date: 星期二, 22 四月 2025 10:58:08 +0800
Subject: [PATCH] 合成片头片尾

---
 yudao-module-digitalcourse/yudao-module-digitalcourse-biz/src/main/java/cn/iocoder/yudao/module/digitalcourse/service/coursemedia/CourseMediaServiceImpl.java |  487 ++++++++++++++++++++++++++++++++----------------------
 1 files changed, 289 insertions(+), 198 deletions(-)

diff --git a/yudao-module-digitalcourse/yudao-module-digitalcourse-biz/src/main/java/cn/iocoder/yudao/module/digitalcourse/service/coursemedia/CourseMediaServiceImpl.java b/yudao-module-digitalcourse/yudao-module-digitalcourse-biz/src/main/java/cn/iocoder/yudao/module/digitalcourse/service/coursemedia/CourseMediaServiceImpl.java
index 8935f32..f60d051 100644
--- a/yudao-module-digitalcourse/yudao-module-digitalcourse-biz/src/main/java/cn/iocoder/yudao/module/digitalcourse/service/coursemedia/CourseMediaServiceImpl.java
+++ b/yudao-module-digitalcourse/yudao-module-digitalcourse-biz/src/main/java/cn/iocoder/yudao/module/digitalcourse/service/coursemedia/CourseMediaServiceImpl.java
@@ -92,48 +92,48 @@
     public PageResult<CourseMediaDO> getCourseMediaPage(CourseMediaPageReqVO pageReqVO) {
         PageResult<CourseMediaDO> courseMediaDOPageResult = courseMediaMapper.selectPage(pageReqVO);
         for (CourseMediaDO courseMediaDO : courseMediaDOPageResult.getList()) {
-           if (courseMediaDO.getStatus() == 1 || courseMediaDO.getStatus() == 0) {
-               //瑙嗛鍚堟垚涓� 鏌ヨ鎺掗槦鍜屽悎鎴愯繘搴�
-               Long id = courseMediaDO.getCourseId();
-               int pos = mediaTaskManager.getQueuePosition(id);
-               if (pos == -1) {
-                   //涓嶅湪闃熷垪涓紝璇存槑宸茬粡鍚堟垚瀹屾垚
-                   courseMediaDO.setStatus(3);
-                   courseMediaMapper.updateById(courseMediaDO);
-               }
-               if (pos == 0) {
-                   //姝e湪鍚堟垚涓�
-                   String reqJson = courseMediaDO.getReqJson();
-                   CourseMediaMegerVO courseMediaMegerVO = JSON.parseObject(reqJson, CourseMediaMegerVO.class);
-                   int size = courseMediaMegerVO.getScenes().size();
-                   String s = configApi.getConfigValueByKey(HEYGEM_FACE2FACE) + "/temp/";
-                   //鏌ヨs涓嬮潰鐨勬枃浠�
-                   File folder = new File(s);
-                   int count = 0;
+            if (courseMediaDO.getStatus() == 1 || courseMediaDO.getStatus() == 0) {
+                //瑙嗛鍚堟垚涓� 鏌ヨ鎺掗槦鍜屽悎鎴愯繘搴�
+                Long id = courseMediaDO.getCourseId();
+                int pos = mediaTaskManager.getQueuePosition(id);
+                if (pos == -1) {
+                    //涓嶅湪闃熷垪涓紝璇存槑宸茬粡鍚堟垚瀹屾垚
+                    courseMediaDO.setStatus(3);
+                    courseMediaMapper.updateById(courseMediaDO);
+                }
+                if (pos == 0) {
+                    //姝e湪鍚堟垚涓�
+                    String reqJson = courseMediaDO.getReqJson();
+                    CourseMediaMegerVO courseMediaMegerVO = JSON.parseObject(reqJson, CourseMediaMegerVO.class);
+                    int size = courseMediaMegerVO.getScenes().size();
+                    String s = configApi.getConfigValueByKey(HEYGEM_FACE2FACE) + "/temp/";
+                    //鏌ヨs涓嬮潰鐨勬枃浠�
+                    File folder = new File(s);
+                    int count = 0;
 
-                   if (folder.exists() && folder.isDirectory()) {
-                       File[] files = folder.listFiles();
-                       if (files != null) {
-                           for (File file : files) {
-                               if (file.isFile() && file.getName().endsWith("-r.mp4")) {
-                                   count++;
-                                   System.out.println("鍖归厤鏂囦欢: " + file.getName());
-                               }
-                           }
-                       }
-                       System.out.println("鎬昏鍖归厤 -r.mp4 鏂囦欢鏁伴噺: " + count);
-                   } else {
-                       System.out.println("璺緞涓嶅瓨鍦ㄦ垨涓嶆槸鐩綍");
-                   }
-                   if (count+1>size){
-                       courseMediaDO.setProgressVideo((count) + "/" + size);
-                   }else{
-                       courseMediaDO.setProgressVideo((count)+"/"+size);
+                    if (folder.exists() && folder.isDirectory()) {
+                        File[] files = folder.listFiles();
+                        if (files != null) {
+                            for (File file : files) {
+                                if (file.isFile() && file.getName().endsWith("-r.mp4")) {
+                                    count++;
+                                    System.out.println("鍖归厤鏂囦欢: " + file.getName());
+                                }
+                            }
+                        }
+                        System.out.println("鎬昏鍖归厤 -r.mp4 鏂囦欢鏁伴噺: " + count);
+                    } else {
+                        System.out.println("璺緞涓嶅瓨鍦ㄦ垨涓嶆槸鐩綍");
+                    }
+                    if (count+1>size){
+                        courseMediaDO.setProgressVideo((count) + "/" + size);
+                    }else{
+                        courseMediaDO.setProgressVideo((count)+"/"+size);
 
-                   }
-               }
-               courseMediaDO.setPos(pos);
-           }
+                    }
+                }
+                courseMediaDO.setPos(pos);
+            }
 
         }
         return courseMediaDOPageResult;
@@ -256,215 +256,306 @@
      */
     @Override
     public CommonResult createCompositeVideo(CourseMediaSubtitlesReqVO courseMediaSubtitlesReqVO) {
-        //鐢熸垚鏃堕棿鎴�
+        // 鐢熸垚鏃堕棿鎴�
         String timestamp = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
-        // 鐗囧ご鍦板潃
+
+        // 鐗囧ご銆佺墖灏惧拰瑙嗛鍦板潃
         String titles = courseMediaSubtitlesReqVO.getTitles();
         titles = configApi.getConfigValueByKey("easegen.url") + titles.substring(titles.lastIndexOf("/"));
-
-        // 鐗囧熬鍦板潃
         String trailer = courseMediaSubtitlesReqVO.getTrailer();
         trailer = configApi.getConfigValueByKey("easegen.url") + trailer.substring(trailer.lastIndexOf("/"));
-
         String videoUrl = courseMediaSubtitlesReqVO.getVideoUrl();
         String previewUrl = courseMediaSubtitlesReqVO.getPreviewUrl();
 
         List<String> videoUrls = new ArrayList<>();
         videoUrls.add(titles);
-        String mainVideoPath = "";
+
+        // 妫�鏌ユ槸鍚︽湁涓昏棰戞垨棰勮瑙嗛
         if (videoUrl != null) {
-            mainVideoPath = configApi.getConfigValueByKey("easegen.url") + videoUrl.substring(videoUrl.lastIndexOf("/"));
-            videoUrls.add(mainVideoPath);
-            videoUrls.add(mainVideoPath);
+            videoUrl = configApi.getConfigValueByKey("easegen.url") + videoUrl.substring(videoUrl.lastIndexOf("/"));
+            videoUrls.add(videoUrl);
+            videoUrls.add(trailer);
         } else if (previewUrl != null) {
-            mainVideoPath = configApi.getConfigValueByKey("easegen.url") + previewUrl.substring(previewUrl.lastIndexOf("/"));
-            videoUrls.add(mainVideoPath);
-            videoUrls.add(mainVideoPath);
+            previewUrl = configApi.getConfigValueByKey("easegen.url") + previewUrl.substring(previewUrl.lastIndexOf("/"));
+            videoUrls.add(previewUrl);
+            videoUrls.add(trailer);
         }
-        // 鎻愬彇涓昏棰戠殑鍙傛暟
-        List<String> mainVideoParams = extractMainVideoParams(mainVideoPath);
-        if (mainVideoParams.isEmpty()) {
-            System.err.println("Failed to extract parameters from main video.");
-            return CommonResult.error(BAD_REQUEST.getCode(), "鍚堟垚澶辫触");
-        }
-        // 鍒ゆ柇鏂囦欢澶规槸鍚﹀瓨鍦紝濡傛灉涓嶅瓨鍦ㄥ氨鍒涘缓
+
+        // 鍒ゆ柇鏂囦欢澶规槸鍚﹀瓨鍦紝濡傛灉涓嶅瓨鍦ㄥ垯鍒涘缓
         String filePath = configApi.getConfigValueByKey(HEYGEM_FACE2FACE) + "/compositeVideo/";
         File file = new File(filePath);
         if (!file.exists()) {
             file.mkdirs();
         }
-        // 鍒涘缓txt 鏂囦欢
-        try {
-            createVideosFile(titles, mainVideoPath, trailer);
+
+        // 鐢熸垚瑙嗛鏂囦欢鍒楄〃
+        String fileListPath = configApi.getConfigValueByKey(HEYGEM_FACE2FACE) + "/compositeVideo/" + timestamp + ".txt";
+        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileListPath))) {
+            for (String path : videoUrls) {
+                writer.write("file '" + path + "'\n");
+            }
+            System.out.println("鏂囦欢鍒楄〃宸茬敓鎴愶細" + fileListPath);
         } catch (IOException e) {
-            System.err.println("Error creating videos.txt file: " + e.getMessage());
-            return CommonResult.error(BAD_REQUEST.getCode(), "鍚堟垚澶辫触");
+            e.printStackTrace();
         }
-        // 杈撳嚭鏂囦欢璺緞
-        String outputFilePath = configApi.getConfigValueByKey(HEYGEM_FACE2FACE) + "/compositeVideo/" + timestamp + ".mp4";
-        // 浣跨敤 FFmpeg 鍚堝苟瑙嗛骞跺簲鐢ㄤ富瑙嗛鐨勫弬鏁�
-        mergeVideos(outputFilePath, mainVideoParams,titles,mainVideoPath,trailer);
 
-        System.out.println("Video merging completed.");
+        // 鍘绘帀 courseMediaSubtitlesReqVO.getCourseName() 涓殑绌烘牸鍜岀壒娈婂瓧绗�
+        String newFileName = courseMediaSubtitlesReqVO.getCourseName().replaceAll("[\\s\\p{Punct}]", "");
 
-        byte[] bytes = FileUtil.readBytes(FileUtil.file(outputFilePath));
+        // 鑾峰彇涓昏棰戝垎杈ㄧ巼
+        String videoInfo = getVideoResolution(videoUrls.get(1)); // 浣跨敤涓昏棰� URL
+        String[] resolution = videoInfo.split("x");
+        String width = resolution[0];
+        String height = resolution[1];
+        boolean hasAudio = checkAudio(titles);
+        try {
+            ProcessBuilder builder = null;
+            if (hasAudio) {
+                // 瑙嗛鍖呭惈闊抽锛屾墽琛岀浉搴旂殑鍛戒护
+                builder = new ProcessBuilder(
+                        "ffmpeg",
+                        "-i", titles,
+                        "-vf", "scale="+width+":"+height+":force_original_aspect_ratio=decrease,pad="+width+":"+height+":(ow-iw)/2:(oh-ih)/2,setsar=1",
+                        "-c:v", "libx264", "-preset", "veryfast",
+                        "-c:a", "aac", "-shortest", configApi.getConfigValueByKey(HEYGEM_FACE2FACE) + "/compositeVideo/" + timestamp + "_intro.mp4"
+                );
+            } else {
+                // 瑙嗛涓嶅寘鍚煶棰戯紝鐢熸垚绌洪煶棰戝苟鍚堟垚
+                builder = new ProcessBuilder(
+                        "ffmpeg",
+                        "-i", titles,
+                        "-f", "lavfi", "-t", "10", "-i", "anullsrc=channel_layout=stereo:sample_rate=44100",
+                        "-filter_complex", "[0:v]scale="+width+":"+height+":force_original_aspect_ratio=decrease,pad="+width+":"+height+":(ow-iw)/2:(oh-ih)/2,setsar=1[v]",
+                        "-map", "[v]", "-map", "1:a",
+                        "-c:v", "libx264", "-preset", "veryfast",
+                        "-c:a", "aac", "-shortest", configApi.getConfigValueByKey(HEYGEM_FACE2FACE) + "/compositeVideo/" + timestamp + "_intro.mp4"
+                );
+            }
+            builder.redirectErrorStream(true);
+            Process process = null;
+            try {
+                process = builder.start();
+
+                // 浣跨敤 try-with-resources 纭繚娴佸叧闂�
+                try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
+                    String line;
+                    while ((line = reader.readLine()) != null) {
+                        System.out.println(line);
+                    }
+                }
+
+                // 绛夊緟 FFmpeg 杩涚▼瀹屾垚
+                int exitCode = process.waitFor();
+                if (exitCode != 0) {
+                    throw new RuntimeException("FFmpeg 鎵ц澶辫触锛岄��鍑虹爜锛�" + exitCode);
+                }
+
+                System.out.println("鐗囧ご鍜岀墖灏惧凡璋冩暣鍒嗚鲸鐜囧苟娣诲姞闊宠建");
+
+            } catch (IOException | InterruptedException e) {
+                throw new RuntimeException("FFmpeg 鎵ц寮傚父", e);
+            } finally {
+                // 纭繚 Process 鐨勮緭鍏�/閿欒娴佽鍏抽棴
+                if (process != null) {
+                    try {
+                        process.getInputStream().close();
+                        process.getErrorStream().close();
+                        process.getOutputStream().close();
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        } catch (Exception  e) {
+            e.printStackTrace();
+        }
+
+        boolean hasAudio1 = checkAudio(trailer);
+        try {
+            ProcessBuilder builder = null;
+            if (hasAudio1) {
+                // 瑙嗛鍖呭惈闊抽锛屾墽琛岀浉搴旂殑鍛戒护
+                builder = new ProcessBuilder(
+                        "ffmpeg",
+                        "-i", trailer,
+                        "-vf", "scale="+width+":"+height+":force_original_aspect_ratio=decrease,pad="+width+":"+height+":(ow-iw)/2:(oh-ih)/2,setsar=1",
+                        "-c:v", "libx264", "-preset", "veryfast",
+                        "-c:a", "aac", "-shortest", configApi.getConfigValueByKey(HEYGEM_FACE2FACE) + "/compositeVideo/" + timestamp + "_outro.mp4"
+                );
+            } else {
+                // 瑙嗛涓嶅寘鍚煶棰戯紝鐢熸垚绌洪煶棰戝苟鍚堟垚
+                builder = new ProcessBuilder(
+                        "ffmpeg",
+                        "-i", trailer,
+                        "-f", "lavfi", "-t", "10", "-i", "anullsrc=channel_layout=stereo:sample_rate=44100",
+                        "-filter_complex", "[0:v]scale="+width+":"+height+":force_original_aspect_ratio=decrease,pad="+width+":"+height+":(ow-iw)/2:(oh-ih)/2,setsar=1[v]",
+                        "-map", "[v]", "-map", "1:a",
+                        "-c:v", "libx264", "-preset", "veryfast",
+                        "-c:a", "aac", "-shortest", configApi.getConfigValueByKey(HEYGEM_FACE2FACE) + "/compositeVideo/" + timestamp + "_outro.mp4"
+                );
+            }
+            builder.redirectErrorStream(true);
+            Process process = null;
+            try {
+                process = builder.start();
+
+                // 浣跨敤 try-with-resources 纭繚娴佸叧闂�
+                try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
+                    String line;
+                    while ((line = reader.readLine()) != null) {
+                        System.out.println(line);
+                    }
+                }
+
+                // 绛夊緟 FFmpeg 杩涚▼瀹屾垚
+                int exitCode = process.waitFor();
+                if (exitCode != 0) {
+                    throw new RuntimeException("FFmpeg 鎵ц澶辫触锛岄��鍑虹爜锛�" + exitCode);
+                }
+
+                System.out.println("鐗囧ご鍜岀墖灏惧凡璋冩暣鍒嗚鲸鐜囧苟娣诲姞闊宠建");
+
+            } catch (IOException | InterruptedException e) {
+                throw new RuntimeException("FFmpeg 鎵ц寮傚父", e);
+            } finally {
+                // 纭繚 Process 鐨勮緭鍏�/閿欒娴佽鍏抽棴
+                if (process != null) {
+                    try {
+                        process.getInputStream().close();
+                        process.getErrorStream().close();
+                        process.getOutputStream().close();
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        } catch (Exception  e) {
+            e.printStackTrace();
+        }
+        // 鍚堝苟涓変釜瑙嗛锛氱墖澶淬�佷富瑙嗛銆佺墖灏�
+        ProcessBuilder builder10 = new ProcessBuilder(
+                "ffmpeg",
+                "-i", filePath + timestamp + "_intro.mp4",
+                "-i", videoUrls.get(1),
+                "-i", filePath + timestamp + "_outro.mp4",
+                "-filter_complex", "[0:v][0:a][1:v][1:a][2:v][2:a]concat=n=3:v=1:a=1[v][a]",
+                "-map", "[v]",
+                "-map", "[a]",
+                "-c:v", "libx264",
+                "-preset", "veryfast",
+                "-c:a", "aac",
+                "-shortest",
+                configApi.getConfigValueByKey(HEYGEM_FACE2FACE) + "/compositeVideo/" + timestamp + "_final.mp4"
+        );
+
+        Process process10 = null;
+        builder10.redirectErrorStream(true);
+        try {
+            process10 = builder10.start();
+
+            // 浣跨敤 try-with-resources 纭繚娴佸叧闂�
+            try (BufferedReader reader = new BufferedReader(new InputStreamReader(process10.getInputStream()))) {
+                String line;
+                while ((line = reader.readLine()) != null) {
+                    System.out.println(line);
+                }
+            }
+
+            // 绛夊緟 FFmpeg 杩涚▼瀹屾垚
+            int exitCode = process10.waitFor();
+            if (exitCode != 0) {
+                throw new RuntimeException("FFmpeg 鍚堟垚瑙嗛澶辫触锛岄��鍑虹爜锛�" + exitCode);
+            }
+
+            System.out.println("瑙嗛宸叉垚鍔熷悎鎴�");
+
+        } catch (IOException | InterruptedException e) {
+            throw new RuntimeException("FFmpeg 鍚堟垚瑙嗛寮傚父", e);
+        }
+
+        byte[] bytes = FileUtil.readBytes(FileUtil.file(configApi.getConfigValueByKey(HEYGEM_FACE2FACE) + "/compositeVideo/" + timestamp + "_final.mp4"));
         String compositeVideo = fileApi.createFile(bytes);
-
-        // 鏇存柊鏁版嵁搴撹褰�
         CourseMediaDO courseMediaDO = new CourseMediaDO();
         courseMediaDO.setId(courseMediaSubtitlesReqVO.getId());
         courseMediaDO.setCompositeVideo(compositeVideo);
         int i = courseMediaMapper.updateById(courseMediaDO);
+        //鍒犻櫎鏂囦欢
+        FileUtil.del(configApi.getConfigValueByKey(HEYGEM_FACE2FACE) + "/compositeVideo/" + timestamp + "_intro.mp4");
+        FileUtil.del(configApi.getConfigValueByKey(HEYGEM_FACE2FACE) + "/compositeVideo/" + timestamp + "_outro.mp4");
+        FileUtil.del(configApi.getConfigValueByKey(HEYGEM_FACE2FACE) + "/compositeVideo/" + timestamp + "_final.mp4");
+        FileUtil.del(configApi.getConfigValueByKey(HEYGEM_FACE2FACE) + "/compositeVideo/" + timestamp + ".txt");
 
-        // 鍒犻櫎涓存椂鏂囦欢
-        FileUtil.del(outputFilePath);
-        System.out.println("涓存椂鏂囦欢宸插垹闄�");
-
-        if (i > 0) {
+        if (i>0){
             return CommonResult.success("鍚堟垚鎴愬姛");
         }
-        return CommonResult.error(BAD_REQUEST.getCode(), "鍚堟垚澶辫触");
+        return CommonResult.error(BAD_REQUEST.getCode(),"鍚堟垚澶辫触");
     }
-
-    private static void createVideosFile(String introVideoPath, String mainVideoPath, String outroVideoPath) throws IOException {
-        File videosFile = new File("videos.txt");
-        StringBuilder content = new StringBuilder();
-        content.append("file '").append(introVideoPath).append("'\n");
-        content.append("file '").append(mainVideoPath).append("'\n");
-        content.append("file '").append(outroVideoPath).append("'\n");
-
-        java.nio.file.Files.write(videosFile.toPath(), content.toString().getBytes());
-    }
-
-    private static List<String> extractMainVideoParams(String mainVideoPath) {
-        List<String> params = new ArrayList<>();
-        ProcessBuilder processBuilder = new ProcessBuilder(
-                "ffmpeg",
-                "-i", mainVideoPath
+    public String getVideoResolution(String videoFilePath) {
+        ProcessBuilder builder = new ProcessBuilder(
+                "ffprobe",
+                "-v", "error", // 浠呮樉绀洪敊璇�
+                "-select_streams", "v:0", // 閫夋嫨瑙嗛娴�
+                "-show_entries", "stream=width,height", // 浠呮樉绀哄搴﹀拰楂樺害
+                "-of", "default=noprint_wrappers=1:nokey=1", // 鏍煎紡鍖栬緭鍑�
+                videoFilePath // 瑙嗛鏂囦欢璺緞
         );
 
+        Process process = null;
+        String resolution = "";
         try {
-            Process process = processBuilder.start();
+            process = builder.start();
 
-            BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
-            String line;
-            while ((line = errorReader.readLine()) != null) {
-                if (line.contains("Video:")) {
-                    String videoInfo = line.split(":")[1].trim();
-                    String codec = videoInfo.split(", ")[0];
-                    params.add("-c:v");
-                    params.add(codec);
-                } else if (line.contains("Audio:")) {
-                    String audioInfo = line.split(":")[1].trim();
-                    String codec = audioInfo.split(", ")[0];
-                    String bitrate = audioInfo.split(", ")[1].split("\\s+")[0];
-                    params.add("-c:a");
-                    params.add(codec);
-                    params.add("-b:a");
-                    params.add(bitrate);
+            // 璇诲彇 ffprobe 杈撳嚭娴�
+            try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
+                String line;
+                while ((line = reader.readLine()) != null) {
+                    resolution += line + " "; // 鎷兼帴瀹藉害鍜岄珮搴�
                 }
             }
 
+            // 绛夊緟 ffprobe 杩涚▼瀹屾垚
             int exitCode = process.waitFor();
-            if (exitCode == 0) {
-                System.out.println("Parameters extracted successfully.");
-            } else {
-                System.err.println("Parameter extraction failed with exit code: " + exitCode);
+            if (exitCode != 0) {
+                throw new RuntimeException("ffprobe 鎵ц澶辫触锛岄��鍑虹爜锛�" + exitCode);
             }
+
         } catch (IOException | InterruptedException e) {
-            System.err.println("Error during parameter extraction: " + e.getMessage());
+            throw new RuntimeException("ffprobe 鎵ц寮傚父", e);
+        } finally {
+            if (process != null) {
+                try {
+                    process.getInputStream().close();
+                    process.getErrorStream().close();
+                    process.getOutputStream().close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
         }
 
-        return params;
+        // 杩斿洖鍒嗚鲸鐜囷紝鏍煎紡濡� "1920x1080"
+        return resolution.trim().replaceAll("\\s+", "x");
     }
-
-    private static void mergeVideos(String outputPath, List<String> mainVideoParams, String introVideoPath, String mainVideoPath, String outroVideoPath) {
-        List<String> command = new ArrayList<>();
-        command.add("ffmpeg");
-        command.add("-f");
-        command.add("concat");
-        command.add("-safe");
-        command.add("0");
-        command.add("-i");
-        command.add("videos.txt");
-
-        // 娣诲姞鏄犲皠閫夐」浠ョ‘淇濋煶棰戞祦鐨勪竴鑷存��
-        command.add("-map");
-        command.add("[v]");
-        command.add("-map");
-        command.add("[a]");
-
-        // 娣诲姞杩囨护鍣ㄩ�夐」浠ュ鐞嗘棤澹伴煶鎯呭喌
-        double introDuration = getDurationInSeconds(introVideoPath);
-        double mainDuration = getDurationInSeconds(mainVideoPath);
-        double outroDuration = getDurationInSeconds(outroVideoPath);
-
-        StringBuilder filterComplex = new StringBuilder();
-        filterComplex.append("[0:v][0:a?]overlay=enable='between(t,0,");
-        filterComplex.append(introDuration);
-        filterComplex.append(")'[v0];");
-        filterComplex.append("[1:v][1:a?]overlay=enable='between(t,");
-        filterComplex.append(introDuration);
-        filterComplex.append(",");
-        filterComplex.append(introDuration + mainDuration);
-        filterComplex.append(")'[v1];");
-        filterComplex.append("[2:v][2:a?]overlay=enable='gt(t,");
-        filterComplex.append(introDuration + mainDuration);
-        filterComplex.append(")'[v2];");
-        filterComplex.append("[v0][v1][v2]concat=n=3:v=1:a=0[v];");
-        filterComplex.append("[0:a]aresample=async=1:first_pts=0[a0];");
-        filterComplex.append("[1:a]aresample=async=1:first_pts=0[a1];");
-        filterComplex.append("[2:a]aresample=async=1:first_pts=0[a2];");
-        filterComplex.append("[a0][a1][a2]amerge=inputs=3[a]");
-
-        command.add("-filter_complex");
-        command.add(filterComplex.toString());
-
-        // 娣诲姞涓昏棰戠殑鍙傛暟
-        command.addAll(mainVideoParams);
-        command.add(outputPath);
-
-        ProcessBuilder processBuilder = new ProcessBuilder(command);
-
+    private static boolean checkAudio(String inputFile) {
         try {
-            Process process = processBuilder.start();
-
+            ProcessBuilder builder = new ProcessBuilder(
+                    "ffprobe", "-i", inputFile,
+                    "-show_streams", "-select_streams", "a",
+                    "-loglevel", "error"
+            );
+            Process process = builder.start();
             BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
             String line;
             while ((line = reader.readLine()) != null) {
-                System.out.println(line);
+                if (line.contains("codec_type=audio")) {
+                    return true; // 闊抽娴佸瓨鍦�
+                }
             }
-
             int exitCode = process.waitFor();
-            if (exitCode == 0) {
-                System.out.println("Video merged successfully.");
-            } else {
-                System.err.println("Video merging failed with exit code: " + exitCode);
-            }
+            return exitCode == 0;
         } catch (IOException | InterruptedException e) {
-            System.err.println("Error during video merging: " + e.getMessage());
-        }
-    }
-
-    private static double getDurationInSeconds(String videoPath) {
-        ProcessBuilder processBuilder = new ProcessBuilder(
-                "ffprobe",
-                "-v", "error",
-                "-show_entries", "format=duration",
-                "-of", "default=noprint_wrappers=1:nokey=1",
-                videoPath
-        );
-
-        try {
-            Process process = processBuilder.start();
-            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
-            String durationStr = reader.readLine();
-            double duration = Double.parseDouble(durationStr);
-            process.waitFor();
-            return duration;
-        } catch (IOException | InterruptedException | NumberFormatException e) {
-            System.err.println("Error getting duration of video: " + e.getMessage());
-            return 0.0;
+            e.printStackTrace();
+            return false;
         }
     }
 }

--
Gitblit v1.9.3