| | |
| | | import java.time.LocalDateTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.*; |
| | | import java.util.concurrent.Future; |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.stream.Collectors; |
| | | |
| | |
| | | } |
| | | |
| | | @Async |
| | | public CommonResult createCompositeVideo(CourseMediaSubtitlesReqVO courseMediaSubtitlesReqVO) { |
| | | public void createCompositeVideo(CourseMediaSubtitlesReqVO courseMediaSubtitlesReqVO) { |
| | | //片头地址 |
| | | String titles = courseMediaSubtitlesReqVO.getTitles(); |
| | | titles = configApi.getConfigValueByKey("easegen.url") + titles.substring(titles.lastIndexOf("/")); |
| | |
| | | //去掉updateReqVO.getName()中的空格和特殊字符 |
| | | String newFileName = courseMediaSubtitlesReqVO.getCourseName().replaceAll("[\\s\\p{Punct}]", ""); |
| | | ProcessBuilder builder = new ProcessBuilder( |
| | | "ffmpeg", "-f", "concat", "-safe","0", "-i",fileListPath , "-c", "copy", configApi.getConfigValueByKey(HEYGEM_FACE2FACE)+"/compositeVideo/"+newFileName+".mp4" |
| | | // q |
| | | "ffmpeg", "-f", "concat", "-safe", "0", "-i", fileListPath, "-c", "copy", |
| | | configApi.getConfigValueByKey(HEYGEM_FACE2FACE) + "/compositeVideo/" + newFileName + ".mp4" |
| | | ); |
| | | builder.redirectErrorStream(true); |
| | | Process process = null; |
| | | try { |
| | | process = builder.start(); |
| | | // 读取 FFmpeg 输出(可选) |
| | | BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); |
| | | System.out.println(builder.command()); |
| | | System.out.println("最终视频已生成"); |
| | | |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | // 使用 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(); |
| | | } |
| | | } |
| | | } |
| | | byte[] bytes = FileUtil.readBytes(FileUtil.file(configApi.getConfigValueByKey(HEYGEM_FACE2FACE) +"/compositeVideo/"+newFileName+".mp4")); |
| | | String compositeVideo = fileApi.createFile(bytes); |
| | | CourseMediaDO courseMediaDO = new CourseMediaDO(); |
| | | courseMediaDO.setId(courseMediaSubtitlesReqVO.getId()); |
| | | courseMediaDO.setCompositeVideo(compositeVideo); |
| | | int i = courseMediaMapper.updateById(courseMediaDO); |
| | | if (i>0){ |
| | | return CommonResult.success("视频合成成功"); |
| | | } |
| | | return CommonResult.error(BAD_REQUEST.getCode(),"视频合成失败"); |
| | | courseMediaMapper.updateById(courseMediaDO); |
| | | System.out.println(); |
| | | } |
| | | } |