功能需求

  • 实现高质量视频文件的压缩
  • 像素等比例

在这里插入图片描述

代码如下

引入依赖

<dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv-platform</artifactId>
    <version>1.5.6</version>
</dependency>

工具类

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.springframework.web.multipart.MultipartFile;

import java.io.IOException;

/**
 * 视频压缩工具类
 */
public class VideoCompressionUtil {

    /**
     * 压缩视频
     *
     * @param file
     * @param outputPath
     * @throws Exception
     */
    public static void compressVideo(MultipartFile file, String outputPath) throws IOException {
        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(file.getInputStream());
        grabber.start();

        // 自动计算保持比例的高度
        int width = grabber.getImageWidth();
        int height = grabber.getImageHeight();
        if (width > 1920) {
            width = 1920;
            height = (int) (width * ((double) grabber.getImageHeight() / grabber.getImageWidth()));
        } else if (width > 1280) {
            width = 1280;
            height = (int) (width * ((double) grabber.getImageHeight() / grabber.getImageWidth()));
        } else if (width > 1080) {
            width = 1080;
            height = (int) (width * ((double) grabber.getImageHeight() / grabber.getImageWidth()));
        }

        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputPath, width, height, grabber.getAudioChannels());

        // 视频编码配置
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        recorder.setVideoBitrate(2000000); // 2.5Mbps
        recorder.setVideoOption("threads", "0"); // 0=自动选择最佳线程数
        recorder.setVideoOption("preset", "fast"); // 调整预设(preset)级别
        recorder.setVideoOption("crf", "28"); // 默认23,增大可提速但降低质量
        recorder.setVideoOption("bf", "2"); // 默认3,减少B帧可提速
        recorder.setVideoOption("bufsize", "10000k"); // 增加缓冲区大小,默认可能只有2000k
        recorder.setFrameRate(grabber.getFrameRate());
        recorder.setGopSize((int) grabber.getFrameRate() * 3); // 关键帧间隔3秒
        recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);

        // 音频配置(保持原音频)
        recorder.setAudioCodec(grabber.getAudioCodec());
        recorder.setAudioBitrate(grabber.getAudioBitrate());
        recorder.setSampleRate(grabber.getSampleRate());

        recorder.start();

        Frame frame;
        while ((frame = grabber.grabFrame()) != null) {
            recorder.record(frame);
        }

        recorder.stop();
        recorder.release();
        grabber.stop();
        grabber.release();
    }

}

在这里插入图片描述

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐