使用javacv和ffmpeg框架简单快速的合并mp4文件的视频和音频
1.依赖
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.5.1</version>
</dependency>
<!-- 视频处理包 -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>ffmpeg-platform</artifactId>
<version>4.1.3-1.5.1</version>
</dependency>
2.测试类
可以根据自己的需要进行封装
package com.test.demo;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber;
import org.bytedeco.javacv.FrameRecorder;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.ArrayList;
import java.util.List;
import static org.bytedeco.ffmpeg.global.avutil.AV_LOG_ERROR;
@SpringBootTest
public class MP4Test {
public static void main(String[] args) throws FrameRecorder.Exception, FrameGrabber.Exception {
List<String> file = new ArrayList<>();
// 添加需要合并的mp4文件
file.add("C:\Users\Administrator\Desktop\1\source\1.mp4");
file.add("C:\Users\Administrator\Desktop\1\source\2.mp4");
long start = System.currentTimeMillis();
// 合并
videoMerge(file, "C:\Users\Administrator\Desktop\1\1\5.mp4");
// 统计耗时
System.out.println("耗时" + (System.currentTimeMillis() - start) + "毫秒");
}
/**
* 多个视频的合并
*
* @param videoList 地址集合
* @param output 合并后的视频输出地址
*/
public static void videoMerge(List<String> videoList, String output) throws FrameRecorder.Exception, FrameGrabber.Exception {
// 帧抓取器 以第一个视频为蓝本开始抓取
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(videoList.get(0));
// 载入
grabber.start();
// 配置帧解码器
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(output, grabber.getImageWidth(), grabber.getImageHeight(), 2);
// 视频编解码器
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
//设置音频编解码器
recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
// 单通道
recorder.setAudioChannels(2);
recorder.setInterleaved(true);
// 输出流封装格式
recorder.setFormat("mp4");
// 视频帧率
recorder.setFrameRate(grabber.getFrameRate());
recorder.setSampleRate(grabber.getSampleRate());
// 设置日志输出(error)
avutil.av_log_set_level(AV_LOG_ERROR);
// 设置分辨率格式 yuv420p
recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
//设置视频比特率或者音频比特率
int videoBitrate = grabber.getVideoBitrate();
int audioBitrate = grabber.getAudioBitrate();
recorder.setVideoBitrate(videoBitrate > 0 ? videoBitrate : 400000); // 默认视频比特率
recorder.setAudioBitrate(audioBitrate > 0 ? audioBitrate : 128000); // 默认音频比特率
// 开始编码
recorder.start();
Frame frame;
for (String videoPath : videoList) {
try (FFmpegFrameGrabber grabberTemp = new FFmpegFrameGrabber(videoPath)) {
grabberTemp.start();
// 处理视频和音频帧
while ((frame = grabberTemp.grab()) != null) {
if (frame.image != null) {
recorder.record(frame); // 记录视频帧
} else if (frame.samples != null) {
recorder.record(frame); // 记录音频帧
}
}
}
}
// 关闭帧编解码器
recorder.close();
grabber.close();
}
}