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

前言:时隔一年多了,不知不觉博客停更那么久了,那不忘初心还记得吗?
最近在做音视频相关的开发,没什么资料并且之前也没有接触过这方面,
咨询了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、总结

在这里插入图片描述

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值