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