Java使用javacv处置惩罚视频文件过程记录

打印 上一主题 下一主题

主题 925|帖子 925|积分 2775

最近接到一个需求是将.mp4/.m4v文件体积进行压缩,我使用javacv中的FFmpegFrameGrabber、FFmpegFrameFilter、FFmpegFrameRecorder简单的实现视频帧的抓取、过滤、录制与输出。
性能暂未验证。文章对这次的过程进行记录。
1.jdk的选择
mcr.microsoft.com/java/jdk:8u222-zulu-centos
2.maven依赖
  1. `<dependency>
  2.             <groupId>org.bytedeco</groupId>
  3.             <artifactId>javacv</artifactId>
  4.             <version>1.4.4</version>
  5. </dependency>
  6. <dependency>
  7.             <groupId>org.bytedeco</groupId>
  8.             <artifactId>javacv-platform</artifactId>
  9.             <version>1.4.4</version>
  10. </dependency>`
复制代码
3.实现过程
  1. import lombok.extern.slf4j.Slf4j;
  2. import org.bytedeco.javacpp.avcodec;
  3. import org.bytedeco.javacpp.avutil;
  4. import org.bytedeco.javacv.FFmpegFrameFilter;
  5. import org.bytedeco.javacv.FFmpegFrameGrabber;
  6. import org.bytedeco.javacv.FFmpegFrameRecorder;
  7. import org.bytedeco.javacv.Frame;
  8. import org.junit.Test;
  9. @Slf4j
  10. public class CoverVideoImageResolution {
  11.     @Test
  12.     public void changeResolution() {
  13.         String inputFilePath = "原文件地址";
  14.         String outputFilePath = "目标文件地址";
  15.         // 创建一个视频帧抓取器
  16.         FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputFilePath);
  17.         // 创建一个视频帧过滤器,用于修改视频分辨率
  18.         FFmpegFrameFilter frameFilter = new FFmpegFrameFilter("scale=720:480", grabber.getImageWidth(), grabber.getImageHeight());
  19.         // 创建一个视频帧录制器,用于将处理后的视频帧写入输出文件
  20.         FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputFilePath, 720, 480);
  21.         try {
  22.             long now = System.currentTimeMillis();
  23.             // 开始从输入文件中抓取视频帧
  24.             grabber.start();
  25.             log.info("Video Frame Rate:{};",grabber.getFrameRate());
  26.             log.info("Video Width:{};",grabber.getImageWidth());
  27.             log.info("Video Height:{};",grabber.getImageHeight());
  28.             log.info("Video Bitrate:{};",grabber.getVideoBitrate());
  29.             log.info("Video Sample Rate:{};",grabber.getSampleRate());
  30.             log.info("Video Codec:{};",grabber.getVideoCodec());
  31.             // 启动视频帧过滤器
  32.             frameFilter.start();
  33.             // 设置输出视频的格式,与输入视频相同
  34.             recorder.setFormat(grabber.getFormat());
  35.             // 设置视频的采样率和帧速率与输入视频相同
  36.             recorder.setSampleRate(grabber.getSampleRate());
  37.             recorder.setFrameRate(grabber.getFrameRate());
  38.             // 设置视频比特率,值越大视频质量越好,文件体积也越大,可根据需要调整
  39.             log.info("原视频比特率:{}", grabber.getVideoBitrate());
  40.             //CRF 的值范围是0到51,其中 0 表示无损压缩,而 51 表示质量非常差的压缩
  41.             recorder.setOption("crf","28");
  42.             // 设置视频比特率
  43.             recorder.setVideoBitrate(grabber.getVideoBitrate()/2);
  44.             // 设置视频编解码器为h.264
  45.             recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); // 设置视频编解码器为h.264
  46.             // 设置像素格式为YUV420P
  47.             recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
  48.             // 设置音频参数
  49.             recorder.setAudioChannels(2); // 设置音频通道数
  50.             recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC); // 设置音频编解码器
  51.             recorder.setSampleRate(grabber.getSampleRate()); // 设置音频采样率
  52.             recorder.setAudioBitrate(grabber.getAudioBitrate()); // 音频比特率
  53.             // 启动视频帧录制器
  54.             recorder.start();
  55.             Frame frame;
  56.             // 处理视频帧并将处理后的帧写入输出文件
  57.             while ((frame = grabber.grab()) != null) {
  58.                 frameFilter.push(frame);// 将抓取的视频帧传递给过滤器
  59.                 Frame filteredFrame = frameFilter.pull();// 获取过滤后的视频帧
  60.                 recorder.record(filteredFrame);// 将过滤后的视频帧写入输出文件
  61.             }
  62.             // 停止视频帧抓取器、过滤器和录制器
  63.             grabber.stop();
  64.             frameFilter.stop();
  65.             recorder.stop();
  66.             System.out.println("Video resolution modified successfully.");
  67.             log.info("压缩耗时:{}秒",  (System.currentTimeMillis()-now)/1000);
  68.         } catch (Exception e) {
  69.             e.printStackTrace();
  70.         }
  71.     }
  72. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

自由的羽毛

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表