前言:时隔一年多了,不知不觉博客停更那么久了,那不忘初心还记得吗?
最近在做音视频相关的开发,没什么资料并且之前也没有接触过这方面,
咨询了T届的好友,拿到了下面的这张表情包,问题是当我百度的时候才
发现与我想要知道的相关文档是没有一篇能满足,东拼西凑的找文档,可
还是没办法实现想要的功能,于是我陷入了沉思......最终还是轻松搞定
了这个需求,于是我打开了csdn想给后人留一片树荫。
最后奉上工具的学习资料(感兴趣的可以看看),废话不多说!!!!!
FFmpeg是啥: ffmpeg(命令行工具) 是一个快速的音视频转换工具。
FFmpeg能干啥:如果你用过爱剪辑的话或者其他一些音视频处理软件的话,你可以理解他们能做的你用玩意都能做。
为啥要用FFmpeg:开源免费啊,你用软件要收费呢,但是这不是关键,核心是你要整合进Java,怎么用Java和执行它,也就是你咋去写个爱剪辑呢(当然呢那种东西靠一个两个人也是很难写出来的,本文结合实际情况处理一下小问题还是绰绰有余)。
FFmpeg先去这学习一下再来看哦
需要将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格式并指定声道和采样率;
当时了解到的技术选型就是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 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 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 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告诉你。


