VideoUtil.java 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package com.fdkankan.fusion.common.util;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.apache.commons.lang3.StringUtils;
  4. import org.bytedeco.ffmpeg.avcodec.AVPacket;
  5. import org.bytedeco.ffmpeg.global.avcodec;
  6. import org.bytedeco.ffmpeg.global.avutil;
  7. import org.bytedeco.javacpp.Loader;
  8. import org.bytedeco.javacv.FFmpegFrameGrabber;
  9. import org.bytedeco.javacv.FFmpegFrameRecorder;
  10. import org.bytedeco.javacv.Frame;
  11. import java.io.*;
  12. import java.util.*;
  13. @Slf4j
  14. public class VideoUtil {
  15. /**
  16. * 多个视频的合并
  17. * @param videoAddrSet 地址集合
  18. * @param output 合并后的视频输出地址
  19. */
  20. public static String videoMerge(LinkedHashSet<String> videoAddrSet, String output)
  21. throws org.bytedeco.javacv.FrameRecorder.Exception, org.bytedeco.javacv.FrameGrabber.Exception {
  22. File tagFile = new File(output);
  23. if(!tagFile.exists()){
  24. tagFile.mkdirs();
  25. }
  26. String fileName = UUID.randomUUID().toString().replace("-","")+".mp4";
  27. output +="/"+fileName;
  28. List<String> videoList = new ArrayList<>(videoAddrSet);
  29. FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(videoList.get(0));
  30. grabber.start();
  31. FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(output, grabber.getImageWidth(),
  32. grabber.getImageHeight(), 0);
  33. recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
  34. // recorder.setAudioChannels(1);
  35. // recorder.setInterleaved(true);
  36. recorder.setFormat("mp4");
  37. recorder.setFrameRate(grabber.getFrameRate());
  38. recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P); // yuv420p
  39. int bitrate = grabber.getVideoBitrate();
  40. if (bitrate == 0) {
  41. bitrate = grabber.getAudioBitrate();
  42. }
  43. recorder.setVideoBitrate(bitrate);
  44. recorder.start();
  45. Frame frame = null;
  46. for (; (frame = grabber.grabImage()) != null;) {
  47. // 封装/复用
  48. recorder.record(frame);
  49. }
  50. for(int i=1;i<videoList.size();i++) {
  51. FFmpegFrameGrabber grabberTemp = new FFmpegFrameGrabber(videoList.get(i));
  52. grabberTemp.start();
  53. for (; (frame = grabberTemp.grabImage()) != null;) {
  54. // 封装/复用
  55. recorder.record(frame);
  56. }
  57. grabberTemp.close();
  58. }
  59. recorder.close();
  60. grabber.close();
  61. return fileName;
  62. }
  63. public static String mergeVideo(LinkedHashSet<String> fromVideoFileList, String newVideoFile) {
  64. File tagFile = new File(newVideoFile);
  65. if(!tagFile.exists()){
  66. tagFile.mkdirs();
  67. }
  68. String fileName = UUID.randomUUID().toString().replace("-","")+".mp4";
  69. try {
  70. List<String> voidTS = new ArrayList<>();
  71. for (String fromVideoFile : fromVideoFileList) {
  72. String format = "%s -y -i %s -vcodec copy -bsf:v h264_mp4toannexb -f mpegts %s";
  73. String name = fromVideoFile.substring(0, fromVideoFile.lastIndexOf("."));
  74. String command = String.format(format, "ffmpeg", fromVideoFile, newVideoFile +"/"+name + ".ts");
  75. execCommand(command);
  76. voidTS.add(name + ".ts");
  77. }
  78. StringBuilder tsPath = new StringBuilder();
  79. tsPath.append("ffmpeg");
  80. tsPath.append(" -i ");
  81. tsPath.append("concat:");
  82. for (int t = 0; t < voidTS.size(); t++) {
  83. if (t != voidTS.size() - 1) {
  84. tsPath.append(voidTS.get(t) + "|");
  85. } else {
  86. tsPath.append(voidTS.get(t));
  87. }
  88. }
  89. tsPath.append(" -vcodec ");
  90. tsPath.append(" copy ");
  91. tsPath.append(" -bsf:a ");
  92. tsPath.append(" aac_adtstoasc ");
  93. tsPath.append(" -movflags ");
  94. tsPath.append(" +faststart ");
  95. tsPath.append(newVideoFile +"/"+fileName);
  96. execCommand(tsPath.toString());
  97. //删除生成的ts文件
  98. for (String filePath : voidTS) {
  99. File file = new File(filePath);
  100. file.delete();
  101. }
  102. return fileName;
  103. } catch (Exception e) {
  104. e.printStackTrace();
  105. log.error(" 合并失败-{}", e.getMessage());
  106. return null;
  107. }
  108. }
  109. private static void execCommand(String command) throws IOException {
  110. log.info("执行command: {}",command);
  111. Process pr = Runtime.getRuntime().exec(command);
  112. pr.getOutputStream().close();
  113. pr.getInputStream().close();
  114. pr.getErrorStream().close();
  115. try {
  116. pr.waitFor();
  117. Thread.sleep(1000);
  118. } catch (InterruptedException e) {
  119. e.printStackTrace();
  120. } finally {
  121. pr.destroy();
  122. }
  123. }
  124. }