Java使用javacv处理视频文件过程记录
最近接到一个需求是将.mp4/.m4v文件体积进行压缩,我使用javacv中的FFmpegFrameGrabber、FFmpegFrameFilter、FFmpegFrameRecorder简单的实现视频帧的抓取、过滤、录制与输出。
性能暂未验证。文章对这次的过程进行记录。
1.jdk的选择
mcr.microsoft.com/java/jdk:8u222-zulu-centos
2.maven依赖
`<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.4.4</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.4.4</version>
</dependency>`
3.实现过程
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.javacpp.avcodec;
import org.bytedeco.javacpp.avutil;
import org.bytedeco.javacv.FFmpegFrameFilter;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import org.junit.Test;
@Slf4j
public class CoverVideoImageResolution {
@Test
public void changeResolution() {
String inputFilePath = "原文件地址";
String outputFilePath = "目标文件地址";
// 创建一个视频帧抓取器
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputFilePath);
// 创建一个视频帧过滤器,用于修改视频分辨率
FFmpegFrameFilter frameFilter = new FFmpegFrameFilter("scale=720:480", grabber.getImageWidth(), grabber.getImageHeight());
// 创建一个视频帧录制器,用于将处理后的视频帧写入输出文件
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputFilePath, 720, 480);
try {
long now = System.currentTimeMillis();
// 开始从输入文件中抓取视频帧
grabber.start();
log.info("Video Frame Rate:{};",grabber.getFrameRate());
log.info("Video Width:{};",grabber.getImageWidth());
log.info("Video Height:{};",grabber.getImageHeight());
log.info("Video Bitrate:{};",grabber.getVideoBitrate());
log.info("Video Sample Rate:{};",grabber.getSampleRate());
log.info("Video Codec:{};",grabber.getVideoCodec());
// 启动视频帧过滤器
frameFilter.start();
// 设置输出视频的格式,与输入视频相同
recorder.setFormat(grabber.getFormat());
// 设置视频的采样率和帧速率与输入视频相同
recorder.setSampleRate(grabber.getSampleRate());
recorder.setFrameRate(grabber.getFrameRate());
// 设置视频比特率,值越大视频质量越好,文件体积也越大,可根据需要调整
log.info("原视频比特率:{}", grabber.getVideoBitrate());
//CRF 的值范围是0到51,其中 0 表示无损压缩,而 51 表示质量非常差的压缩
recorder.setOption("crf","28");
// 设置视频比特率
recorder.setVideoBitrate(grabber.getVideoBitrate()/2);
// 设置视频编解码器为h.264
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); // 设置视频编解码器为h.264
// 设置像素格式为YUV420P
recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
// 设置音频参数
recorder.setAudioChannels(2); // 设置音频通道数
recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC); // 设置音频编解码器
recorder.setSampleRate(grabber.getSampleRate()); // 设置音频采样率
recorder.setAudioBitrate(grabber.getAudioBitrate()); // 音频比特率
// 启动视频帧录制器
recorder.start();
Frame frame;
// 处理视频帧并将处理后的帧写入输出文件
while ((frame = grabber.grab()) != null) {
frameFilter.push(frame);// 将抓取的视频帧传递给过滤器
Frame filteredFrame = frameFilter.pull();// 获取过滤后的视频帧
recorder.record(filteredFrame);// 将过滤后的视频帧写入输出文件
}
// 停止视频帧抓取器、过滤器和录制器
grabber.stop();
frameFilter.stop();
recorder.stop();
System.out.println("Video resolution modified successfully.");
log.info("压缩耗时:{}秒", (System.currentTimeMillis()-now)/1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!