Java实现批量视频抽帧2.0

继上个版本 对其进行略微升级 🤓

上个版本仅对一个视频进行抽帧处理

此版本可对一个文件夹内的全部视频进行抽帧并对应的文件夹进行帧图片的保存

1️⃣配置pom.xml (保持上次不变)

复制代码
    <dependencies>
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv-platform</artifactId>
            <version>1.5.7</version>
        </dependency>

    </dependencies>

2️⃣创建Util工具类 (本次所有方法都在次类中)

复制代码
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;

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

public class Util {
    //读取文件夹的内容并执行1️⃣创建文件夹2️⃣抽帧
    public static String ReadFolderFiles(String address) {
        //存放读取到的路径
        ArrayList<String> strings = new ArrayList<>();
        // 文件夹路径
        String folderPath = address;
        // 创建File对象
        File folder = new File(folderPath);
        // 检查文件夹是否存在
        if (folder.exists() && folder.isDirectory()) {
            int num;
            String strCreate = "";
            String strFrame = "";
            // 获取文件夹中的所有文件名
            File[] files = folder.listFiles();
            // 将子文件夹的名称添加到ArrayList中并过滤掉当前文件夹名
            for (File file : files) {
                if (!file.getName().equals(".DS_Store")) {
                    strings.add(file.getName());
                }
            }
            num = strings.size();
            // 输出文件名数组
            for (String fileName : strings) {
                String oldfileName = address+"/"+fileName;
                String str = fileName.substring(0,fileName.indexOf('.'));
                String newFileName = address+"/"+str;
                strCreate = CreateFolder(newFileName);
                strFrame = FrameExtractor(oldfileName);
            }
            return String.format(strCreate+"\n已对%d个视频进行抽帧\n"+strFrame+"至对应文件夹",num);
        } else {
            return "指定的文件夹不存在或不是一个文件夹";
        }
    }
    //1️⃣根据视频名称创建对应文件夹
    private static String CreateFolder(String fileName){
        String str;
        // 文件夹名
        String folderName = fileName;
        // 创建一个File对象,表示文件夹路径
        File folder = new File(folderName);
        // 使用mkdir()方法创建文件夹
        if (!folder.exists()) {
            if (folder.mkdir()) {
                str = "文件夹创建成功!";
            } else {
                str = "文件夹创建失败!";
            }
        } else {
            str = "文件夹已存在!";
        }
        return str;
    }
    //2️⃣将视频转为帧图片
    public static String FrameExtractor(String address){
        String str;
        // 视频文件路径
        String videoFilePath = address;
        // 创建FFmpegFrameGrabber对象
        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(videoFilePath);
        try {
            // 打开视频文件
            grabber.start();
            // 逐帧抓取视频
            Frame frame;
            int frameNumber = 1;
            //保存路径
            String createaddress = address.substring(0,address.indexOf("."));
            while ((frame = grabber.grabImage()) != null) {
                BufferedImage bufferedImage = frameToBufferedImage(frame);
                // 生成保存帧图像的文件路径
                String outputFilePath = String.format("%s/frame_%05d.jpg", createaddress, frameNumber);
                // 保存帧图像到文件
                try {
                    ImageIO.write(bufferedImage, "jpg", new File(outputFilePath));
                } catch (IOException e) {
                    e.printStackTrace();
                    str = "保存失败";
                }
                frameNumber++;
            }
            // 关闭视频文件
            grabber.stop();
            str = "保存成功";
        } catch (org.bytedeco.javacv.FrameGrabber.Exception e) {
            e.printStackTrace();
            str = "保存失败";
        }
        return str;
    }
    //将Frame转换为BufferedImage
    private static BufferedImage frameToBufferedImage(Frame frame) {
        Java2DFrameConverter converter = new Java2DFrameConverter();
        return converter.getBufferedImage(frame);
    }
}

3️⃣运行结果

相关推荐
冬天vs不冷3 分钟前
SpringBoot条件注解全解析:核心作用与使用场景详解
java·spring boot·python
百锦再23 分钟前
Android Studio 实现自定义全局悬浮按钮
android·java·ide·app·android studio·安卓
百锦再26 分钟前
Android Studio 项目文件夹结构详解
android·java·ide·ios·app·android studio·idea
阿达King哥42 分钟前
Java虚拟机(JVM)平台无关?相关?
java·jvm
不是AI1 小时前
【Java编程】【计算机视觉】一种简单的图片加/解密算法
java·算法·计算机视觉
小小福仔1 小时前
Python爬虫第四战(使用防盗链下载视频)
爬虫·python·音视频·反爬·防盗链referer
森叶1 小时前
Java NIO & Java 虚拟线程(微线程)与 Go 协程的运行原理不同 为何Go 能在低配机器上承接10万 Websocket 协议连接
java·websocket·nio
程序员小蘇1 小时前
一天一个java知识点----Tomcat与Servlet
java·servlet·tomcat
Moso_Rx1 小时前
JavaEE——线程安全
java·安全·java-ee
岁岁岁平安2 小时前
SpringMVC入门学习总结(2025.04.16)
java·spring·java-ee·mvc·springmvc