You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无需ProcessBuilder/Runtime.exec,用Java的FFmpeg CLI Wrapper获取视频帧率

用FFmpeg Java Wrapper获取视频帧率(无需手动启动外部进程)

你可以通过FFmpeg Java Wrapper中的FFprobe组件解析视频元数据来获取帧率,无需手动调用ProcessBuilder或Runtime.exec。以下是具体实现:

实现getFrameRate方法

public double getFrameRate(String videoPath) {
    FFprobe ffprobe;
    try {
        ffprobe = new FFprobe();
    } catch (IOException e) {
        throw new RuntimeException("初始化FFprobe失败", e);
    }

    // 解析视频文件元数据
    FFprobeResult probeResult = ffprobe.probe(videoPath);
    
    // 筛选视频流并提取帧率
    return probeResult.getStreams()
            .stream()
            .filter(stream -> "video".equals(stream.getCodecType()))
            .findFirst()
            .map(stream -> stream.getRFrameRate())
            .map(this::parseFrameRate)
            .orElseThrow(() -> new IllegalArgumentException("目标文件中未找到视频流"));
}

// 解析FFprobe返回的帧率字符串(支持"24/1"这类分数格式或"23.976"这类直接数值)
private double parseFrameRate(String frameRateStr) {
    String[] rateParts = frameRateStr.split("/");
    if (rateParts.length == 2) {
        double numerator = Double.parseDouble(rateParts[0]);
        double denominator = Double.parseDouble(rateParts[1]);
        return numerator / denominator;
    }
    return Double.parseDouble(frameRateStr);
}

优化截图方法的动态帧率使用

把原代码中硬编码的24替换为动态获取的帧率,避免固定值带来的误差:

public void captureScreenshots(String videoPath, String outputPath, int intervalInSeconds) {
    FFmpeg ffmpeg;
    try {
        ffmpeg = new FFmpeg();
    } catch (IOException e) {
        throw new RuntimeException("初始化FFmpeg失败", e);
    }
    
    double videoFrameRate = getFrameRate(videoPath);
    int frameInterval = (int) Math.round(videoFrameRate * intervalInSeconds);

    // 动态生成滤镜参数
    String videoFilter = String.format("select='not(mod(n,%d))',setpts='N/(%.2f*TB)'", frameInterval, videoFrameRate);

    FFmpegBuilder builder = new FFmpegBuilder()
            .setInput(videoPath)
            .addOutput(outputPath)
            .setVideoFilter(videoFilter)
            .setFormat("image2")
            .done();

    FFmpegExecutor executor;
    try {
        executor = new FFmpegExecutor(ffmpeg);
    } catch (IOException e) {
        throw new RuntimeException("初始化FFmpegExecutor失败", e);
    }
    executor.createJob(builder).run();
}

关键说明

  • FFprobe是FFmpeg生态中专门用于解析媒体元数据的工具,通过Wrapper调用它比启动转码进程更轻量高效。
  • 帧率字段r_frame_rate通常以分数形式返回(如24fps对应24/1),解析为浮点数值可兼容非整数帧率(如23.976fps)。
  • 确保环境中已安装FFmpeg/FFprobe,若可执行文件路径非默认,可在初始化FFmpeg/FFprobe时通过构造方法指定路径。

内容的提问来源于stack exchange,提问作者Thor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 03:10:26