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

使用java实现ffmpeg的各种操作

以实现如下功能

  • 1、支持音频文件转mp3;
  • 2、支持视频文件转mp4;
  • 3、支持视频提取音频;
  • 4、支持视频中提取缩略图;
  • 5、支持按时长拆分音频文件;

1、工具类

由于部分原因,没有将FfmpegUtil中的静态的命令行与Type枚举类结合使用。


import lombok.extern.slf4j.Slf4j;import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;/***** @author xuancg* 要求系统内置ffmpeg工具环境* @date 2024/9/23*/
@Slf4j
public class FfmpegUtil {private static final String CONVERT_MP3 = "ffmpeg -i %s -y %s";private static final String CONVERT_MP4 = "ffmpeg -i %s -c:v libx264 -c:a copy -y %s";private static final String EXTRACT_MP3 = "ffmpeg -i %s -q:a 0 -map a -y %s";private static final String EXTRACT_ICON = "ffmpeg -i %s -ss 0.5 -vframes 1 -r 1 -ac 2 -ab 128k   -y -f mjpeg %s";private static final String SPLIT_AUDIO_BY_SIZE = "ffmpeg -i %s  -f segment -segment_time  %d  -c copy -y  %s";private static final Set<String> MP3_TYPE = new HashSet<>(Arrays.asList("mp3", "wav", "aac", "flac"));private static final Set<String> MP4_TYPE = new HashSet<>(Arrays.asList("mp4", "avi", "flv", "mpeg", "wmv"));/**** 音视频文件格式化,如果存在目标文件会强制覆盖* 1、支持音频文件转mp3;* 2、支持视频文件转mp4;* 3、支持视频提取音频;* 4、支持视频中提取缩略图;* 5、支持按时长拆分音频文件;*/public static boolean convertMedia(MediaConvertBo convertBo) {File src = convertBo.getSrc();File dest = convertBo.getDest();if (null == src || !src.isFile()) {log.error("原始文件不存在");return false;}if (null != dest && dest.isFile()) {log.info("目标文件已存在");}long start = System.currentTimeMillis();Process process = null;BufferedReader reader = null;try {String cmd = createCmd(convertBo);if(null == cmd){return false;}log.info("ffmpeg执行命令=" + cmd);// 执行命令process = Runtime.getRuntime().exec(cmd);// 获取命令输出结果reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));String line;while ((line = reader.readLine()) != null) {log.debug(line);}// 明确自己的命令需要执行多长时间,否则可以一直等待int timeout = convertBo.getTimeout();if (timeout <= 0) {process.waitFor();} else {process.waitFor(timeout, TimeUnit.SECONDS);}return dest.isFile() && dest.length() > 10;} catch (IOException e) {e.printStackTrace();} catch (InterruptedException e) {log.error("剪裁视频超时source=" + src.getAbsolutePath());} finally {if (null != process) {process.destroy();}if (null != reader) {try {reader.close();} catch (IOException e) {log.error("关闭流失败" + e.getMessage());}}log.info("耗时ms=" + (System.currentTimeMillis() - start));}return false;}public static boolean isMp4File(File file){String name = file.getName();String suffix = name.substring(name.lastIndexOf(".") + 1);return MP4_TYPE.contains(suffix);}public static boolean isMp3File(File file){String name = file.getName();String suffix = name.substring(name.lastIndexOf(".") + 1);return MP3_TYPE.contains(suffix);}private static final String createCmd(MediaConvertBo bo) {File src = bo.getSrc();String srcPath = src.getAbsolutePath().replace("\\", "/");String destPath = bo.getDest().getAbsolutePath().replace("\\", "/");;if (bo.isConvertMp3()) {if(!isMp3File(src)){log.error("错误的mp3格式");return null;}return String.format(CONVERT_MP3, srcPath, destPath);} else if (bo.isConvertMp4()) {if(!isMp4File(src)){log.error("错误的mp4格式");return null;}return String.format(CONVERT_MP4, srcPath, destPath);} else if(bo.getType() == MediaConvertBo.Type.EXTRACT_MP3){if(!isMp4File(src)){log.error("错误的mp4格式");return null;}return String.format(EXTRACT_MP3, srcPath, destPath);} else if(bo.getType() == MediaConvertBo.Type.EXTRACT_ICON) {if(!isMp4File(src)){log.error("错误的mp4格式");return null;}return String.format(EXTRACT_ICON, srcPath , destPath);} else if(bo.getType() == MediaConvertBo.Type.SPLIT_AUDIO_BY_SIZE){bo.getDest().mkdirs();String name = src.getName();String suffix = name.substring(name.lastIndexOf(".") + 1);// 保持输入输出一致性return String.format(SPLIT_AUDIO_BY_SIZE, srcPath, bo.getSplitSize(), destPath + "/output_%03d." + suffix);}log.error("错误的type");return null;}}

2、入参对象


import lombok.Data;import java.io.File;/***** @author xuancg* @date 2024/9/23*/
@Data
public class MediaConvertBo {private File src;private File dest;/**0表示持续等待,单位秒*/private int timeout = 0;/** 拆分时长,单位秒*/private int splitSize = 60;/**处理类型,必传*/private Type type;public boolean isConvertMp3(){return null != type && type == Type.CONVERT_MP3;}public boolean isConvertMp4(){return null != type && type == Type.CONVERT_MP4;}public enum Type {/**将视频转码成mp4*/CONVERT_MP4,/**将音频转码成mp3*/CONVERT_MP3,/**从视频中提取音频*/EXTRACT_MP3,/**从视频中提取缩略图*/EXTRACT_ICON,/**按时长拆分音频文件*/SPLIT_AUDIO_BY_SIZE,;}}

3、junit测试


import org.junit.Test;import java.io.File;/***** @author xuancg* @date 2024/9/23*/
public class ConvertTest {/*** 1分10秒的wav2M大小=转成mp3耗时858ms,200kb大小*/@Testpublic void convertmp3(){File src = new File("C:\\Users\\Desktop\\音视频素材\\example.wav");File dest = new File("C:\\Users\\Desktop\\音视频素材\\example.mp3");MediaConvertBo bo = new MediaConvertBo();bo.setType(MediaConvertBo.Type.CONVERT_MP3);bo.setSrc(src);bo.setDest(dest);System.out.println(FfmpegUtil.convertMedia(bo));}/*** 4分13秒视频50M大小=提取音频耗时7秒,4M大小*/@Testpublic void extractMp3(){File src = new File("C:\\User\\Desktop\\音视频素材\\202002041032546186.mp4");File dest = new File("C:\\User\\Desktop\\音视频素材\\202002041032546186.mp3");MediaConvertBo bo = new MediaConvertBo();bo.setType(MediaConvertBo.Type.EXTRACT_MP3);bo.setSrc(src);bo.setDest(dest);System.out.println(FfmpegUtil.convertMedia(bo));}/*** 耗时500ms,保持原始视频尺寸*/@Testpublic void extractIcon(){File src = new File("C:\\Users\\Desktop\\音视频素材\\202002041032546186.mp4");File dest = new File("C:\\Users\\Desktop\\音视频素材\\202002041032546186.jpg");MediaConvertBo bo = new MediaConvertBo();bo.setType(MediaConvertBo.Type.EXTRACT_ICON);bo.setSrc(src);bo.setDest(dest);System.out.println(FfmpegUtil.convertMedia(bo));}/*** 1分钟2秒*/@Testpublic void splitAudio(){File src = new File("C:\\Users\\Desktop\\音视频素材\\example.wav");File dest = new File("C:\\Users\\Desktop\\音视频素材\\example");MediaConvertBo bo = new MediaConvertBo();bo.setType(MediaConvertBo.Type.SPLIT_AUDIO_BY_SIZE);bo.setSrc(src);bo.setDest(dest);bo.setSplitSize(60);System.out.println(FfmpegUtil.convertMedia(bo));}}

5、maven依赖

<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version> <!-- 版本号可替换为最新版本 --><scope>test</scope>
</dependency><dependency><groupId>org.bytedeco</groupId><artifactId>javacv</artifactId><version>1.5.8</version>
</dependency><!-- 此版本中主要兼容linux和windows系统,如需兼容其他系统平台,请引入对应依赖即可 -->
<dependency><groupId>org.bytedeco</groupId><artifactId>opencv</artifactId><version>4.6.0-1.5.8</version><classifier>linux-x86_64</classifier>
</dependency>
<dependency><groupId>org.bytedeco</groupId><artifactId>opencv</artifactId><version>4.6.0-1.5.8</version><classifier>windows-x86_64</classifier>
</dependency>
<dependency><groupId>org.bytedeco</groupId><artifactId>openblas</artifactId><version>0.3.21-1.5.8</version><classifier>linux-x86_64</classifier>
</dependency>
<dependency><groupId>org.bytedeco</groupId><artifactId>openblas</artifactId><version>0.3.21-1.5.8</version><classifier>windows-x86_64</classifier>
</dependency>
<dependency><groupId>org.bytedeco</groupId><artifactId>ffmpeg</artifactId><version>5.1.2-1.5.8</version><classifier>linux-x86_64</classifier>
</dependency>
<dependency><groupId>org.bytedeco</groupId><artifactId>ffmpeg</artifactId><version>5.1.2-1.5.8</version><classifier>windows-x86_64</classifier>
</dependency>

相关文章:

使用java实现ffmpeg的各种操作

以实现如下功能 1、支持音频文件转mp3&#xff1b;2、支持视频文件转mp4&#xff1b;3、支持视频提取音频&#xff1b;4、支持视频中提取缩略图&#xff1b;5、支持按时长拆分音频文件&#xff1b; 1、工具类 由于部分原因&#xff0c;没有将FfmpegUtil中的静态的命令行与Ty…...

【ArcGIS微课1000例】0122:经纬网、方里网、参考格网绘制案例教程

文章目录 一、ArcGIS格网类型二、绘制经纬网三、绘制方里网四、绘制参考格网五、注意事项一、ArcGIS格网类型 在ArcMap中,可以创建三种类型的格网: 经纬网——将地图分割为经线和纬线。经纬网是用来标识准确地理位置的方式,由经线和纬线构成,相对于经纬线,分别有的经度和…...

电路板上电子元件检测系统源码分享

电路板上电子元件检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Comp…...

综合体第三题(DHCP报文分析)

DHCP工作流程&#xff08;一般情况下&#xff09; 例二&#xff08;无忧/22&#xff09; 下图为DHCP客户机获取IP地址等配置信息时&#xff0c;使用Wareshark软件捕获报文中编号为2〜5的4条报文&#xff0c;图中对编号为3的报文进行了解析。分析图中的信息并补全图中①〜⑤处的…...

企业级-pdf预览-前后端

作者&#xff1a;fyupeng 技术专栏&#xff1a;☞ https://github.com/fyupeng 项目地址&#xff1a;☞ https://github.com/fyupeng/distributed-blog-system-api 留给读者 本文 一、介绍 对于PDF预览&#xff0c;有很多开发者都遇到过头疼的难题&#xff0c;今天给大家介绍…...

为什么 qt 成为 c++ 界面编程的第一选择?

一、前言 为什么现在QT越来越成为界面编程的第一选择&#xff0c;笔者从事qt界面编程已经有接近8年&#xff0c;在这之前我做C界面都是基于MFC&#xff0c;也做过5年左右。当时为什么会从MFC转到QT&#xff0c;主要原因是MFC开发界面想做得好看一些十分困难&#xff0c;引用第…...

Day1-顺序表

1. 数据结构-基本概念 数据之间的相互关系&#xff0c;包括三种关系&#xff1a;逻辑结构&#xff1a;表示数据元素之间的抽象关系(如邻接关系、从属关系等)。有四种基本的逻辑结构&#xff1a;集合结构、线性结构、树形结构、图状结构存储结构&#xff1a;数据的逻辑结构在计算…...

PostgreSQL - pgvector 插件构建向量数据库并进行相似度查询

在现代的机器学习和人工智能应用中&#xff0c;向量相似度检索是一个非常重要的技术&#xff0c;尤其是在文本、图像或其他类型的嵌入向量的操作中。本文将介绍如何在 PostgreSQL 中安装 pgvector 插件&#xff0c;用于存储和检索向量数据&#xff0c;并展示如何通过 Python 脚…...

UR机器人坐标系转化

UR机器人读取上来的坐标系是旋转矢量&#xff0c;每次都要查一下怎么转换&#xff0c;在这里记录以下...

【每日一题】LeetCode 2306.公司命名(位运算、数组、哈希表、字符串、枚举)

【每日一题】LeetCode 2306.公司命名&#xff08;位运算、数组、哈希表、字符串、枚举&#xff09; 题目描述 给定一个字符串数组 ideas&#xff0c;表示在公司命名过程中使用的名字列表。我们需要从 ideas 中选择两个不同的名字&#xff0c;称为 ideaA 和 ideaB。然后交换 i…...

240922-chromadb的基本使用

A. 背景介绍 ChromaDB 是一个较新的开源向量数据库&#xff0c;专为高效的嵌入存储和检索而设计。与其他向量数据库相比&#xff0c;ChromaDB 更加专注于轻量化、简单性和与机器学习模型的无缝集成。它的核心目标是帮助开发者轻松管理和使用高维嵌入向量&#xff0c;特别是与生…...

工厂模式和抽象工厂模式的实验报告

1. 实验结果&#xff1a; 记录并附上不同模型对象&#xff08;例如&#xff1a;士兵、机器人、骑士&#xff09;的展示效果截图。 2. 性能分析&#xff1a; 记录并比较抽象工厂模式与直接实例化的性能测试结果&#xff0c;分析它们在不同数量级对象创建时的开销与效益。 2.1…...

C标准库<string.h>-str、strn开头的函数

char *strcat(char *dest, const char *src) 函数功能 strcat 函数用于将一个字符串追加到另一个字符串的尾部。 参数解释 dest&#xff1a;指向目标字符串的指针&#xff0c;这个字符串的尾部将被追加 src 字符串的内容。src&#xff1a;指向源字符串的指针&#xff0c;其…...

Anaconda/Miniconda的删除和安装

要在 MacBook 上删除 Anaconda 或 Miniconda,并重新安装它,您可以按照以下步骤进行操作。 删除 Anaconda/Miniconda 1. 删除 Anaconda/Miniconda 文件和目录 打开 终端 并运行以下命令来删除安装目录。 对于 Anaconda,通常安装在 ~/anaconda3: rm -rf ~/anaconda3对于…...

【Harmony】轮播图特效,持续更新中。。。。

效果预览 swiper官网例子 Swiper 高度可变化 两边等长露出&#xff0c;跟随手指滑动 Swiper 指示器导航点位于 Swiper 下方 卡片楼层层叠一 一、官网 例子 参考代码&#xff1a; // xxx.ets class MyDataSource implements IDataSource {private list: number[] []cons…...

Go 并发模式:管道的妙用

解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在编写程序时,我们通常不会一口气写出一个冗长的函数。相反,我们通过构建函数、结构体和方法等抽象来简化代码。这不仅有助于隐藏不重要的细节,还使我们能够专注于某一部分代码,而不必担心影响其他部分。然而…...

CAN通信详解

1、CAN介绍 1.1、什么是CAN? CAN&#xff08;Controller Area Network&#xff09; 即控制器局域网&#xff0c;是ISO国际标准化的串行通信协议。 开发目的&#xff1a;为了满足汽车产业的“减少线束的数量”、“通过多个LAN&#xff0c;进行大量数据的高速通信”…...

52 文本预处理_by《李沐:动手学深度学习v2》pytorch版

系列文章目录 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 文章目录 系列文章目录一、理论部分二、代码读取数据集词元化词表整合所有功能小结练习 一、理论部分 对于序列数据处理问题&#xff0c;我们在序列处理中评估了所需的统计工具和预测时面临的挑战。 …...

【python】字符串扩展-格式化的精度控制

字符串扩展 字符串的三种定义方式字符串拼接字符串格式化格式化的精度控制字符串格式化方式2对表达式进行格式化 学习目标 掌握格式化字符串的过程中做数字的精度控制 字符串格式化 name "小明" set_up_year 2006 stock_price 19.99 message "我是&…...

C++第一次练习

题目1 class Solution { public:bool isletter(char s){if(s<z&&s>a)return true;if(s>A&&s<Z)return true;return false;}string reverseOnlyLetters(string s) {if(s.empty()){return s;}int left,right;left0;rights.size()-1;while(left<ri…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中&#xff0c;网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时&#xff0c;开发者迫切需要一套高效、可靠且跨平台的调试方案。过去&#xff0c;我们或多或少使用过 Chrome DevTools、Remote Debug…...

SQL Server 触发器调用存储过程实现发送 HTTP 请求

文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...

【Veristand】Veristand环境安装教程-Linux RT / Windows

首先声明&#xff0c;此教程是针对Simulink编译模型并导入Veristand中编写的&#xff0c;同时需要注意的是老用户编译可能用的是Veristand Model Framework&#xff0c;那个是历史版本&#xff0c;且NI不会再维护&#xff0c;新版本编译支持为VeriStand Model Generation Suppo…...

二维FDTD算法仿真

二维FDTD算法仿真&#xff0c;并带完全匹配层&#xff0c;输入波形为高斯波、平面波 FDTD_二维/FDTD.zip , 6075 FDTD_二维/FDTD_31.m , 1029 FDTD_二维/FDTD_32.m , 2806 FDTD_二维/FDTD_33.m , 3782 FDTD_二维/FDTD_34.m , 4182 FDTD_二维/FDTD_35.m , 4793...