当前位置: 首页 > article >正文

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️⃣运行结果


http://www.kler.cn/a/231871.html

相关文章:

  • Essential Cell Biology--Fifth Edition--Chapter one (8)
  • AI 提示词(Prompt)入门 十:最佳实践|详细询问,提供细节!
  • stdin文件流指针
  • 丹摩征文活动|丹摩助力selenium实现大麦网抢票
  • 躺平成长-人工智能进行编程-(12)
  • 2024年09月CCF-GESP编程能力等级认证Python编程三级真题解析
  • 前端架构: 脚手架的开发流程和常用框架
  • 基于“python+”潮汐、风驱动循环、风暴潮等海洋水动力模拟实践技术
  • macOS系统下彻底删除应用程序和其数据、配置等
  • 《Git 简易速速上手小册》第1章:Git 基础(2024 最新版)
  • Python进阶----在线翻译器(Python3的百度翻译爬虫)
  • get通过发送Body传参-工具类
  • Go 语言中如何大小端字节序?int 转 byte 是如何进行的?
  • 小白水平理解面试经典题目LeetCode 21. Merge Two Sorted Lists【Linked List类】
  • 【Web - 框架 - Vue】随笔 - 通过`CDN`的方式使用`VUE 2.0`和`Element UI`
  • CDN相关和HTTP代理
  • nodejs将console.log保存到log.txt文档中(electron工具)
  • 图像处理入门:OpenCV的基础用法解析
  • 09 AB 10串口通信发送原理
  • SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式 基础(持续更新~)
  • PdfFactory Pro软件下载以及序列号注册码生成器
  • 总结-回想2023
  • Java图形化界面编程——Container容器 笔记
  • Netty的常用组件及线程模型设计(二)
  • Markdown:简洁高效的文本标记语言
  • springboot(ssm悦己美容院后台管理系统 美容院管理系统Java系统