package com.fdkankan.fusion.common.util; import com.fdkankan.common.util.CreateObjUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.bytedeco.ffmpeg.avcodec.AVPacket; import org.bytedeco.ffmpeg.global.avcodec; import org.bytedeco.ffmpeg.global.avutil; import org.bytedeco.javacpp.Loader; import org.bytedeco.javacv.FFmpegFrameGrabber; import org.bytedeco.javacv.FFmpegFrameRecorder; import org.bytedeco.javacv.Frame; import java.io.*; import java.util.*; @Slf4j public class VideoUtil { /** * 多个视频的合并 * @param videoAddrSet 地址集合 * @param output 合并后的视频输出地址 */ public static String videoMerge(LinkedHashSet videoAddrSet, String output) throws org.bytedeco.javacv.FrameRecorder.Exception, org.bytedeco.javacv.FrameGrabber.Exception { File tagFile = new File(output); if(!tagFile.exists()){ tagFile.mkdirs(); } String fileName = UUID.randomUUID().toString().replace("-","")+".mp4"; output +="/"+fileName; List videoList = new ArrayList<>(videoAddrSet); FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(videoList.get(0)); grabber.start(); FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(output, grabber.getImageWidth(), grabber.getImageHeight(), 0); recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); // recorder.setAudioChannels(1); // recorder.setInterleaved(true); recorder.setFormat("mp4"); recorder.setFrameRate(grabber.getFrameRate()); recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P); // yuv420p int bitrate = grabber.getVideoBitrate(); if (bitrate == 0) { bitrate = grabber.getAudioBitrate(); } recorder.setVideoBitrate(bitrate); recorder.start(); Frame frame = null; for (; (frame = grabber.grabImage()) != null;) { // 封装/复用 recorder.record(frame); } for(int i=1;i fromVideoFileList, String newVideoFile) { File tagFile = new File(newVideoFile); if(!tagFile.exists()){ tagFile.mkdirs(); } String fileName = UUID.randomUUID().toString().replace("-","")+".mp4"; try { List voidTS = new ArrayList<>(); for (String fromVideoFile : fromVideoFileList) { String format = "%s -y -i %s -vcodec copy -bsf:v h264_mp4toannexb -f mpegts %s"; String name = UUID.randomUUID().toString().replace("-",""); String command = String.format(format, "ffmpeg", fromVideoFile, newVideoFile +"/"+name + ".ts"); CreateObjUtil.callshell(command); voidTS.add(newVideoFile +"/"+name + ".ts"); } StringBuilder tsPath = new StringBuilder(); tsPath.append("ffmpeg"); tsPath.append(" -i "); tsPath.append("concat:"); for (int t = 0; t < voidTS.size(); t++) { if (t != voidTS.size() - 1) { tsPath.append(voidTS.get(t) + "|"); } else { tsPath.append(voidTS.get(t)); } } tsPath.append(" -vcodec "); tsPath.append(" copy "); tsPath.append(" -bsf:a "); tsPath.append(" aac_adtstoasc "); tsPath.append(" -movflags "); tsPath.append(" +faststart "); tsPath.append(newVideoFile).append("/").append(fileName); CreateObjUtil.callshell(tsPath.toString()); //删除生成的ts文件 for (String filePath : voidTS) { File file = new File(filePath); file.delete(); } return fileName; } catch (Exception e) { e.printStackTrace(); log.error(" 合并失败-{}", e.getMessage()); return null; } } }