VideoUtil.java 4.4 KB

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