java 精简使用ffmpeg

xml 复制代码
    <properties>
        <java.version>25</java.version>
        <mybatis-flex.version>1.11.7</mybatis-flex.version>
        <awssdk.version>2.42.21</awssdk.version>
        <javacv.version>1.5.13</javacv.version>
        <ffmpeg.version>8.0.1-${javacv.version}</ffmpeg.version>
        <spring-ai.version>2.0.0</spring-ai.version>
        <spring-ai-session.version>0.6.0</spring-ai-session.version>
    </properties>
     <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv</artifactId>
            <version>${javacv.version}</version>
        </dependency>
            <profiles>
        <profile>
            <id>window</id>
            <dependencies>
                <dependency>
                    <groupId>org.bytedeco</groupId>
                    <artifactId>ffmpeg</artifactId>
                    <version>${ffmpeg.version}</version>
                    <classifier>windows-x86_64</classifier>
                </dependency>
            </dependencies>
        </profile>
        <profile>
            <id>linux</id>
            <dependencies>
                <dependency>
                    <groupId>org.bytedeco</groupId>
                    <artifactId>ffmpeg</artifactId>
                    <version>${ffmpeg.version}</version>
                    <classifier>linux-x86_64</classifier>
                </dependency>
            </dependencies>
        </profile>
    </profiles>
java 复制代码
package com.kongjs.smo.common.util;

import org.bytedeco.javacv.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class FFmpegUtil {
    private static final Logger log = LoggerFactory.getLogger(FFmpegUtil.class);

    public static void captureFirstFrame(String videoPath, String outImgPath, String format) {
        FFmpegFrameGrabber grabber = null;
        Java2DFrameConverter converter = new Java2DFrameConverter();
        try {
            grabber = new FFmpegFrameGrabber(videoPath);
            grabber.start();
            if (grabber.getImageWidth() <= 0 || grabber.getImageHeight() <= 0) {
                return;
            }
            Frame frame = null;
            int tryCount = 0;
            while (tryCount < 100) {
                frame = grabber.grabFrame();
                tryCount++;
                if (frame != null && frame.image != null) {
                    break;
                }
            }
            if (frame == null || frame.image == null) {
                return;
            }
            BufferedImage image = converter.convert(frame);
            ImageIO.write(image, format, new File(outImgPath));
        } catch (FFmpegFrameGrabber.Exception e) {
            // 帧读取器异常
            log.error("FFmpeg解码视频失败:" + e.getMessage());
        } catch (FrameGrabber.Exception e) {
            // FFmpeg 底层解码
            log.error("帧采集器读取异常:" + e.getMessage());
        } catch (IOException e) {
            // 文件流异常
            log.error("文件IO读写失败:" + e.getMessage());
        } finally {
            // 强制释放资源,防止句柄泄漏
            if (grabber != null) {
                try {
                    grabber.stop();
                    grabber.close();
                } catch (Exception ignored) {
                }
            }
        }
    }

    public static void captureFirstFrame(String videoPath, String outImgPath, String format, int thumbWidth, int thumbHeight, int quality) {
        FFmpegFrameGrabber grabber = null;
        FFmpegFrameRecorder recorder = null;
        try {
            grabber = new FFmpegFrameGrabber(videoPath);
            grabber.start();
            if (grabber.getImageWidth() <= 0 || grabber.getImageHeight() <= 0) {
                return;
            }
            Frame frame = null;
            int tryCount = 0;
            while (tryCount < 100) {
                // 抓取关键帧,避免黑屏
                frame = grabber.grabKeyFrame();
                tryCount++;
                if (frame != null && frame.image != null) {
                    break;
                }
            }
            if (frame == null || frame.image == null) {
                return;
            }
            int width = grabber.getImageWidth();
            int height = grabber.getImageHeight();
            recorder = new FFmpegFrameRecorder(outImgPath, width, height);
            recorder.setFormat(format);
            recorder.setVideoQuality(quality);
            recorder.start();
            recorder.record(frame);
        } catch (FFmpegFrameGrabber.Exception e) {
            // 帧读取器异常
            log.error("FFmpeg解码视频失败:" + e.getMessage());
        } catch (FrameGrabber.Exception e) {
            // FFmpeg 底层解码
            log.error("帧采集器读取异常:" + e.getMessage());
        } catch (IOException e) {
            // 文件流异常
            log.error("文件IO读写失败:" + e.getMessage());
        } finally {
            if (recorder != null) {
                try {
                    recorder.close();
                } catch (Exception ignored) {
                }
            }
            // 强制释放资源,防止句柄泄漏
            if (grabber != null) {
                try {
                    grabber.close();
                } catch (Exception ignored) {
                }
            }
        }
    }

    static void main() {
        captureFirstFrame("C:\\Users\\101202104016\\Videos\\Captures\\111111111111111111111111111111.mp4","C:\\Users\\101202104016\\Videos\\Captures\\111111111111111111111111111111.webp",
                "webp",400,400,75);
    }

}
相关推荐
小羊没烦恼!3 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
俊昭喜喜里3 天前
java中的继承和多态的区别
java
小羊没烦恼!3 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
譕痕3 天前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码3 天前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖3 天前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商
此时不提桶,更待何时3 天前
01-06-A-JVM排查实战详解
java·jvm
伞伞悦读3 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
vipxieliang3 天前
ValidX 在 DDD 领域驱动设计中的实践
java·spring boot
C语言小火车3 天前
C/C++ 为什么需要编译器?
开发语言·c++