Java如何整合FFmpeg、FFprobe等音视频处理工具,零基础照样玩

news2024/11/30 8:32:45
前言:时隔一年多了,不知不觉博客停更那么久了,那不忘初心还记得吗?
最近在做音视频相关的开发,没什么资料并且之前也没有接触过这方面,
咨询了T届的好友,拿到了下面的这张表情包,问题是当我百度的时候才
发现与我想要知道的相关文档是没有一篇能满足,东拼西凑的找文档,可
还是没办法实现想要的功能,于是我陷入了沉思......最终还是轻松搞定
了这个需求,于是我打开了csdn想给后人留一片树荫。

最后奉上工具的学习资料(感兴趣的可以看看),废话不多说!!!!!

FFmpeg是啥:​ ffmpeg(命令行工具) 是一个快速的音视频转换工具。
FFmpeg能干啥:如果你用过爱剪辑的话或者其他一些音视频处理软件的话,你可以理解他们能做的你用玩意都能做。
为啥要用FFmpeg:开源免费啊,你用软件要收费呢,但是这不是关键,核心是你要整合进Java,怎么用Java和执行它,也就是你咋去写个爱剪辑呢(当然呢那种东西靠一个两个人也是很难写出来的,本文结合实际情况处理一下小问题还是绰绰有余)。

FFmpeg先去这学习一下再来看哦

1、我的需求

需要将mp3,m4a,m4r,wma,amr,aac,ac3,ape,flac,mmf,ogg类型格式的音频转成wav格式并指定声道和采样率;
需要将mp4,3gp,mov,m4v,mkv,flv,vob,wmv,rm,rmvb,dat,asf,asx,avi类型格式的视频先提取音轨再转成wav格式并指定声道和采样率;

2、设计&编码

当时了解到的技术选型就是ffmpeg工具了,去简单的学习了一下这个工具的基础语法以及音视频开发的基本规范和格式。

于是我写了工具类FFmpegUtils

package com.iflytex.bohai.utils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/**
 * 利用ffmpeg进行音频视频操作,需先下载安装ffmpeg
 */
@Slf4j
@Data
@Configuration
public class FfmpegUtil {
    @Value("${ffmpeg.temppath}")
    private String tempPath;//保存音频、视频的临时文件夹
    @Value("${ffmpeg.ffmpeg-util-path}")
    private String ffmpegUtilPath;//工具包路径

    /**
     * 将音频统一转成wav格式
     * @param inputPath 输入文件
     * @param sampleRate 采样率
     */
    public String transcodeToWav(String inputPath, String sampleRate) throws IOException, InterruptedException {
        createTempDir();
        List<String> command = new ArrayList<>();
        command.add(ffmpegUtilPath);
        command.add("-y");
        command.add("-i");
        command.add(inputPath);
        command.add("-async");
        command.add("1");
        command.add("-ar");
        command.add(sampleRate);
        command.add("-ac");
        command.add("1");
        command.add("-f");
        command.add("wav");
        String outputPath=FilenameUtils.getFullPath(inputPath)+FilenameUtils.getBaseName(inputPath) +".wav";
        command.add(outputPath);
        commandStart(command);
        return outputPath;
    }

    /**
     * 从视频中提取音频为wav
     * @param inputPath 视频文件的路径
     *  @param sampleRate 采样率
     */
    public String getAudioFromVideo(String inputPath,String sampleRate) throws IOException, InterruptedException {
        createTempDir();
        List<String> command = new ArrayList<>();
        command.add(ffmpegUtilPath);
        command.add("-i");
        command.add(inputPath);
        command.add("-ac");
        command.add("1");
        command.add("-ar");
        command.add(sampleRate);
        command.add("-f");
        command.add("wav");
        command.add("-vn");
        String outputPath=FilenameUtils.getFullPath(inputPath)+FilenameUtils.getBaseName(inputPath)+".wav";
        command.add(outputPath);
        commandStart(command);
        return outputPath;
    }
    /**
     * 调用命令行执行
     *
     * @param command 命令行参数
     */
    public static void commandStart(List<String> command) throws IOException, InterruptedException {
        ProcessBuilder builder = new ProcessBuilder();
        //正常信息和错误信息合并输出
        builder.redirectErrorStream(true);
        builder.command(command);
        log.debug(command.toString());
        //开始执行命令
        Process process;
        process = builder.start();
        //如果你想获取到执行完后的信息,那么下面的代码也是需要的
        String line = "";
        BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
        while ((line = br.readLine()) != null) {
            log.debug(line);
        }
        process.waitFor();
        log.debug("命令执行放回code为:"+process.exitValue());
        if(process.exitValue()==1){
            throw new RuntimeException();
        }
    }
    /*
       创建临时目录(用于存储转换后的音视频和原音视频)
       每次使用转换功能是都调用方式目录被删除导致的异常
  */
    public void createTempDir(){
        //如果没有文件夹,则创建
        File tempMediaFile = new File(tempPath);
        if (!tempMediaFile.exists() && !tempMediaFile.isDirectory()) {
            boolean isSuccess = tempMediaFile.mkdirs();
            log.info("初始化音视频临时目录是否成功:{}",isSuccess);
        }
    }

//    /**
//     * 获取ffmpeg的工具路径,根据操作系统去自动选择
//     * @return ffmpeg的工具路径
//     */
//    private  String getFFmpegPath(){ String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
//
//        String ffmpegPath ="./ffmpeg";
//        String os = System.getProperty("os.name");
//        if(os.toLowerCase().startsWith("win")){
//            ffmpegPath ="./ffmpeg.exe";
//        }
//        return ffmpegPath;
//    }

}
process.waitFor();
这句要注意,本地不加不报错因为本地处理速度快,服务器有内耗的话不加这个偶尔就报错的

如果需要其他操作直接仿照我的写法来就好了,具体的命令可以看我上面给点那个链接里面的内容,都是从0告诉你。

3、总结

  • 先去简单了解一下ffmpeg的基础用法
  • 仿照工具类完成一些想要的操作
  • 资料我给你们打包好,免费奉上(工具包的os\win版本,ffmpeg专业化文档)
  • 资料都打包在这里了免费拿取点个赞呗
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/344467.html

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

相关文章

从事架构师岗位快2年了,聊一聊我和ChatGPT对架构的一些感受和看法

从事架构师岗位快2年了&#xff0c;聊一聊我和ChatGPT对架构的一些感受和看法 职位不分高低&#xff0c;但求每天都能有新的进步&#xff0c;永远向着更高的目标前进。 文章目录踏上新的征程架构是什么&#xff1f;架构师到底是干什么的&#xff1f;你的终极目标又是什么&#…

链表带头结点与不带头节点的区别

链表是一种物理存储结构上非连续&#xff0c;非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的 链表可分为&#xff1a;单链表和双链表&#xff0c;带头结点的链表和不带头结点的链表&#xff0c;循环链表和非循环链表 为了表示每个元素与其…

MySQL数据库调优————SQL性能分析

TIPS 本文基于MySQL 8.0 本文探讨如何深入SQL内部&#xff0c;去分析其性能&#xff0c;包括了三种方式&#xff1a; SHOW PROFILEINFORMATION_SCHEMA.PROFILINGPERFORMANCE_SCHEMA SHOW PROFILE SHOW PROFILE是MySQL的一个性能分析命令&#xff0c;可以跟踪SQL各种资源消耗。…

VLAN间通信,看完这个就完全懂了(单臂路由和三层交换)

第九章&#xff1a;实现VLAN间通信 划分VLAN后&#xff0c;由于广播报文只在同VLAN内转发&#xff0c;所以不同VLAN的用户间不能二层互访&#xff0c;这样能起到隔离广播的作用。但实际应用中&#xff0c;不同VLAN的用户又常有互访的需求&#xff0c;此时就需要实现不同VLAN的…

KDNM5000-10A-2剩余电流保护器测试仪

一、产品概述 KDNM5000-10A-2型剩余电流保护器测试仪(以下简称测试仪)&#xff0c;是本公司改进产品&#xff0c;是符合国家标准《剩余电流动作保护器》&#xff08;GB6829—95&#xff09;中第8.3条和GB16917.1—1997中第9.9条验证AC型交流脱扣器动作特性要求的专用测试仪器。…

Nacos微服务笔记

Nacos安装Nacos 的 Github&#xff08;Tags alibaba/nacos GitHub&#xff09;下载我们所需的 Nacos 版本&#xff0c;可以选择 windows 或者 Linux。 进入官网&#xff0c;选择合适版本&#xff0c;tar.gz为linux版本&#xff0c;zip为windows版本。下载并解压 nacos-server…

【C++进阶】一、继承(总)

目录 一、继承的概念及定义 1.1 继承概念 1.2 继承定义 1.3 继承基类成员访问方式的变化 二、基类和派生类对象赋值转换 三、继承中的作用域 四、派生类的默认成员函数 五、继承与友元 六、继承与静态成员 七、菱形继承及菱形虚拟继承 7.1 继承的分类 7.2 菱形虚拟…

【SAP Abap】X-DOC:SE11 - 创建配置表并分配事务码

SE11 - 创建配置表并分配事务码1、创建自定义表2、创建表维护功能3、功能验证4、设置事务码5、带出字段默认值&#xff08;1&#xff09;方法一&#xff1a;表维护事件&#xff08;2&#xff09;方法二&#xff1a;屏幕事件1、创建自定义表 SE11&#xff0c;创建自定义表&…

结构体的三种定义方法、结构体类型名(可选标志符)什么时候可以省略

结构体的三种定义方法 一、单独定义&#xff1a; 先定义结构体类型&#xff0c;再定义变量   定义结构体的格式如下&#xff1a;    struct 结构体名 {    若干数据项&#xff1b;    } &#xff1b;   其中&#xff0c;struct为关键字&#xff1b; 结构体名是用户定…

golang 入门教程:迷你 Twitter 后端

请记住&#xff0c;这个项目主要是为了稍微熟悉下Golang&#xff0c;您可以复制架构&#xff0c;但该项目缺少适当的 ORM&#xff0c;没有适当的身份验证或授权&#xff0c;我完全无视中间件&#xff0c;也没有测试。 我将在其自己的部分中讨论所有这些问题&#xff0c;但重要的…

利用NGROK将本地网站发布为一个公开网站

一般与第三方服务集成时&#xff0c;需要提供https的回调URL&#xff0c;本地开发阶段可以利用NGROK将本地网站发布为公开的https网站。https://ngrok.com/downloadWindow下载地址&#xff1a;https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-windows-amd64.zip以Window…

echarts问题汇总

因为工作中经常使用echarts&#xff0c;做数据可视化相关需求&#xff0c;需要实现各种各样图表的需求。 有遇到过很多问题&#xff0c;一些网上不太好搜索到解决方案的&#xff0c;一直想总结一下解决过程。方便自己查阅&#xff0c;也方便别人参考。 一&#xff1a;echarts…

【C++】set/multiset、map/multimap的使用

目录 一、关联式容器 二、set的介绍 1、接口count与容器multiset 2、接口lower_bound和upper_bound 三、map的介绍 1、接口insert 2、接口insert和operator[]和at 3、容器multimap 四、map和set相关OJ 1、前K个高频单词 2、两个数组的交集 一、关联式容器 vector、…

【LeetCode】环形链表 II [M](链表)

142. 环形链表 II - 力扣&#xff08;LeetCode&#xff09; 一、题目 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链…

Python网络爬虫 学习笔记(1)requests库爬虫

文章目录Requests库网络爬虫requests.get()的基本使用框架requests.get()的带异常处理使用框架&#xff08;重点&#xff09;requests库的其他方法和HTTP协议&#xff08;非重点&#xff09;requests.get()的可选参数网络爬虫引发的问题&#xff08;非重点&#xff09;常见问题…

【C/C++】Windows下VS创建Linux项目

如果不想在Linux下用vim编写代码&#xff0c;可以在Windows下使用VS远程连接Linux&#xff08;Linux下是不支持安装使用VS的&#xff09;&#xff0c;将VS上编写的代码通过 SSH协议 推送到Linux下&#xff0c;注意文件编写是在Windows上进行的&#xff0c;编译是在Linux下进行的…

【Hello Linux】Linux工具介绍 (make/makefile git)

作者&#xff1a;小萌新 专栏&#xff1a;Linux 作者简介&#xff1a;大二学生 希望能和大家一起进步&#xff01; 本篇博客简介&#xff1a;介绍Linux的常用工具make/makefile git Linux项目自动化构建工具 – make/Makefile 背景 会不会写Makefile 从侧面说明了一个人是否具…

Spring Cloud微服务网关Gateway组件

目录 网关简介 什么是Spring Cloud Gateway Spring Cloud Gateway 功能特征 核心概念 工作原理 Spring Cloud Gateway快速开始 环境搭建 集成Nacos 路由断言工厂&#xff08;Route Predicate Factories&#xff09;配置 自定义路由断言工厂 过滤器工厂&#xff08; …

window 配置深度学习环境GPU

CUDA 11.6 CUDNN Anaconda pytorch 参考网址&#xff1a;https://zhuanlan.zhihu.com/p/460806048 阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区 (aliyun.com) 电脑信息 RTX 2060 GPU0 1. CUDA 11.6 1.1 确认信息 C:\Users\thzn>nvidia-smi &#xff08;CUDA Versi…

秒杀项目之消息推送

目录一、创建消费者二、创建订单链路配置2.1 定义RabbitMQ配置类2.2 创建RabbitmqOrderConfig配置类三、如何实现RabbitMQ重复投递机制3.1 开启发送者消息确认模式3.2 消费发送确认3.2.1 创建ConfirmCallBack确认模式3.2.2 创建ReturnCallBack退回模式3.3 创建生产者3.4 创建消…