Java实现批量视频抽帧2.0

news2024/11/17 21:45:30

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

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

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

 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.coloradmin.cn/o/1438224.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

推理系统学习笔记

一些学习资料 最近对MLsys比较感兴趣&#xff0c;遂找些资料开始学习一下 https://fazzie-key.cool/2023/02/21/MLsys/https://qiankunli.github.io/2023/12/16/llm_inference.htmlhttps://dlsyscourse.orghttps://github.com/chenzomi12/DeepLearningSystem/tree/main/04Infe…

数智文旅:智慧文旅中的数字化转型

在数字化浪潮席卷全球的今天&#xff0c;旅游业作为传统服务业的代表&#xff0c;正面临着前所未有的转型压力与机遇。智慧文旅&#xff0c;作为旅游业与数字技术深度融合的产物&#xff0c;不仅标志着旅游业进入了全新的发展阶段&#xff0c;更预示着未来旅游业将朝着更加智能…

QAnything之BCEmbedding技术路线

QAnything和BCEmbedding简介 QAnything[github]是网易有道开源的检索增强生成式应用&#xff08;RAG&#xff09;项目&#xff0c;在有道许多商业产品实践中已经积累丰富的经验&#xff0c;比如有道速读和有道翻译。QAnything是一个支持任意格式文件或数据库的本地知识库问答系…

【开源】JAVA+Vue+SpringBoot实现公司货物订单管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 客户管理模块2.2 商品维护模块2.3 供应商管理模块2.4 订单管理模块 三、系统展示四、核心代码4.1 查询供应商信息4.2 新增商品信息4.3 查询客户信息4.4 新增订单信息4.5 添加跟进子订单 五、免责说明 一、摘要 1.1 项目…

Tauri 的基本使用笔记

文章目录 前言如何将 Tauri 集成到前端项目?进程间通信&#xff08;命令&#xff09;const invoke window.__TAURI__.invoke; 进程间通信&#xff08;事件&#xff09;前端 ⇒ RustRust ⇒ 前端我的疑问 开发时的一些技巧用代码打开前端的开发者工具让 Tauri 不要监听文件Rus…

Leetcode 30天高效刷数据结构和算法 Day1 两数之和 —— 无序数组

两数之和 —— 无序数组 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现…

数据结构(C语言)代码实现(七)——一元多项式的表示与相加

目录 前言 参考资料格式 头文件LinkList.h LocateElem函数&#xff0c;定位查找 有序插入&#xff08;没测试&#xff09; 完整代码 头文件polynomial.h 测试函数&#xff08;主函数&#xff09; 测试结果 前言 寒假在家&#xff0c;有点学不下去&#xff0c;写文章的…

java中ArrayList类常用API

前言&#xff1a;在学习java的ArrayList类的时候&#xff0c;有很多的API需要了解&#xff0c;下面我将举出其中在新手学习时使用频率较大的几个API。 先大体看一下有哪几个&#xff1a;&#xff08;如图&#xff09; 目录 1.add&#xff08;&#xff09; 解释&#xff1a; …

CSS太极动态图

CSS太极动态图 1. 案例效果 我们今天学习用HTML和CSS实现动态的太极&#xff0c;看一下效果。 2. 分析思路 太极图是由两个旋转的圆组成&#xff0c;一个是黑圆&#xff0c;一个是白圆。实现现原理是使用CSS的动画和渐变背景属性。 首先&#xff0c;为所有元素设置默认值为0…

非精线搜索步长规则Armijo规则Goldstein规则Wolfe规则

文章目录 非精确线搜索步长规则Armijo规则Goldstein规则Wolfe规则C示例代码参考链接 非精确线搜索步长规则 在数值优化中&#xff0c;线搜索是一种寻找合适步长的策略&#xff0c;以确保在目标函数上获得足够的下降。如最速下降法&#xff0c;拟牛顿法这些常用的优化算法等&am…

异步解耦之RabbitMQ(三)_RabbitMQ队列

异步解耦之RabbitMQ(一) 异步解耦之RabbitMQ(二)_RabbitMQ架构及交换机 RabbitMQ提供了许多功能和选项&#xff0c;包括队列和消息的 TTL&#xff08;Time-To-Live&#xff0c;生存时间&#xff09;。在本篇博客中&#xff0c;我们将深入探讨 RabbitMQ 队列和消息的 TTL&…

Laykefu客服系统 任意文件上传

【产品介绍】 Laykefu 是一款基于workermangatawayworkerthinkphp5搭建的全功能webim客服系统&#xff0c;旨在帮助企业有效管理和提供优质的客户服务 【漏洞介绍】 Laykefu客服系统/admin/users/upavatar.html接口处存在文件上传漏洞 【资产测绘Query】 fofa语法&#xf…

IS-IS weight影响路由加表

拓扑图 配置 nexthop weight影响路由加入路由表 weight默认为255&#xff0c;取值1~255&#xff0c;值越小越优先 sysname R1 # isis 1is-level level-1cost-style widenetwork-entity 49.1234.0000.0000.0001.00log-peer-change topology # interface GigabitEthernet0/0/0…

freeRTOS总结(十四)任务通知

1、任务通知 任务通知&#xff1a; 用来通知任务的&#xff0c;任务控制块中的结构体成员变量ulNotifiedValue就是这个通知值 使用队列、信号量、事件标志组时都需另外创建一个结构体&#xff0c;通过中间的结构体进行间接通信&#xff01; 使用任务通知时&#xff0c;任务结…

C#上位机与三菱PLC的通信02--MC协议介绍

1、协议介绍 三菱 PLC MC 协议是一种用于三菱 PLC 与上位机之间进行数据通信的协议&#xff0c;也称为 Mitsubishi Communication Protocol。该协议支持串口、以太网等多种通讯方式&#xff0c;可实现实时数据的采集和交换。三菱PLC的MC协议是一种数据通信协议&#xff0c;它用…

跟着pink老师前端入门教程-day21

5.4 常见flex布局思路 5.5 背景线性渐变 语法&#xff1a; background: linear-gradient( 起始方向 , 颜色 1, 颜色 2, ...); background: -webkit-linear-gradient(left, red , blue); background: -webkit-linear-gradient(left top, red , blue); 背景渐变必须添加浏览…

【Mybatis】从0学习Mybatis(1)

前言 本篇文章是从0学习Mybatis的第一篇文章&#xff0c;由于篇幅太长CSDN会限流&#xff0c;因此我打算分开三期来写&#xff0c;这是第一期&#xff01; 1.怎么理解MyBatis是一个框架&#xff1f; 温馨提示&#xff1a;接下来的你不一定能看懂&#xff01; MyBatis是一个J…

1Panel面板如何安装并结合内网穿透实现远程访问本地管理界面

文章目录 前言1. Linux 安装1Panel2. 安装cpolar内网穿透3. 配置1Panel公网访问地址4. 公网远程访问1Panel管理界面5. 固定1Panel公网地址 前言 1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。高效管理,通过 Web 端轻松管理 Linux 服务器&#xff0c;包括主机监控、…

照片去除水印的方法有哪些?这些方法快收藏保存起来

当你踏破铁鞋无觅处&#xff0c;在茫茫网海中寻得心仪的头像或壁纸美图&#xff0c;却发现那完美的画面上赫然带着平台水印&#xff0c;是不是感觉如鲠在喉&#xff1f;但又不知道照片去除水印的方法有哪些而束手无策&#xff1f;别担心&#xff0c;今天我就为你带来几招去水印…

Instagram SEO如何优化?10个技巧

Instagram SEO 是优化 Instagram 内容以使其在平台搜索结果中被发现的做法。如果你希望你可以更快的让你的Ins获得流量&#xff0c;做好SEO就成功了一半。Instagram 搜索结果包括相关内容、帐户、音频、主题标签和地点&#xff0c;下面为你总结10个策略技巧&#xff01; 一、In…