封装类:
ffplay、ffmpeg、ffprobe是安装的ffmpeg路径。


import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;import static java.time.temporal.ChronoUnit.*;/*** 利用ffmpeg进行音频视频操作,需先下载安装ffmpeg*/
public class FfmpegUtils {/*** 下载的ffmpeg解压后的bin目录路径,可配置到环境变量通过配置文件读取*/private static String ffplay = "D:\\Program File\\ffmpeg-4.3.1-2021-01-01-essentials_build\\bin\\ffplay.exe";private static String ffmpeg = "D:\\Program File\\ffmpeg-4.3.1-2021-01-01-essentials_build\\bin\\ffmpeg.exe";private static String ffprobe = "D:\\Program File\\ffmpeg-4.3.1-2021-01-01-essentials_build\\bin\\ffprobe.exe";/*** 提取的音频、合成的视频存放路径,不存在会自动创建*/private static String saveMediaPath = "D:\\ffmpegMedia\\";/*** 保存音频、视频的临时文件夹,不存在会自动创建*/private static String tempMediaPath = "D:\\ffmpegMedia\\temp\\";/*** 保存图片截图的文件夹,不存在会自动创建*/private static String picturMediaPath = "D:\\ffmpegMedia\\pictur\\";static {//如果没有文件夹,则创建File saveMediaFile = new File(saveMediaPath);if (!saveMediaFile.exists() && !saveMediaFile.isDirectory()) {saveMediaFile.mkdirs();}File tempMediaFile = new File(tempMediaPath);if (!tempMediaFile.exists() && !tempMediaFile.isDirectory()) {tempMediaFile.mkdirs();}File picturMediaFile = new File(picturMediaPath);if (!picturMediaFile.exists() && !picturMediaFile.isDirectory()) {picturMediaFile.mkdirs();}}/*** 播放音频和视频** @param resourcesPath 文件的路径*/public static void playVideoAudio(String resourcesPath) {List<String> command = new ArrayList<>();command.add(ffplay);command.add("-window_title");String fileName = resourcesPath.substring(resourcesPath.lastIndexOf("\\") + 1);command.add(fileName);command.add(resourcesPath);//播放完后自动退出//command.add("-autoexit");commandStart(command);}/*** 播放音频和视频并指定循环次数** @param resourcesPath 文件的路径* @param loop          循环播放次数*/public static void playVideoAudio(String resourcesPath, int loop) {List<String> command = new ArrayList<>();command.add(ffplay);command.add("-window_title");String fileName = resourcesPath.substring(resourcesPath.lastIndexOf("\\") + 1);command.add(fileName);command.add(resourcesPath);command.add("-loop");command.add(String.valueOf(loop));//播放完后自动退出//command.add("-autoexit");commandStart(command);}/*** 播放音频和视频并指定宽、高、循环次数** @param resourcesPath 文件的路径* @param weight        宽度* @param height        高度* @param loop          循环播放次数*/public static void playVideoAudio(String resourcesPath, int weight, int height, int loop) {List<String> command = new ArrayList<>();command.add(ffplay);command.add("-window_title");String fileName = resourcesPath.substring(resourcesPath.lastIndexOf("\\") + 1);command.add(fileName);command.add(resourcesPath);command.add("-x");command.add(String.valueOf(weight));command.add("-y");command.add(String.valueOf(height));command.add("-loop");command.add(String.valueOf(loop));//播放完后自动退出//command.add("-autoexit");commandStart(command);}/*** 调用命令行执行** @param command 命令行参数*/public static void commandStart(List<String> command) {command.forEach(v -> System.out.print(v + " "));System.out.println();System.out.println();ProcessBuilder builder = new ProcessBuilder();//正常信息和错误信息合并输出builder.redirectErrorStream(true);builder.command(command);//开始执行命令Process process = null;try {process = builder.start();//如果你想获取到执行完后的信息,那么下面的代码也是需要的String line = "";BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));while ((line = br.readLine()) != null) {System.out.println(line);}} catch (IOException e) {e.printStackTrace();}}/*** 调用命令行执行,并返回信息** @param command 命令行参数*/public static String getInfoStr(List<String> command) {command.forEach(v -> System.out.print(v + " "));System.out.println();System.out.println();ProcessBuilder builder = new ProcessBuilder();//正常信息和错误信息合并输出builder.redirectErrorStream(true);builder.command(command);//开始执行命令Process process = null;StringBuffer sb = new StringBuffer();try {process = builder.start();//如果你想获取到执行完后的信息,那么下面的代码也是需要的String line = "";BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));while ((line = br.readLine()) != null) {System.out.println(line);sb.append(line);}} catch (IOException e) {e.printStackTrace();}return String.valueOf(sb);}/*** 从视频中提取音频为mp3** @param videoResourcesPath 视频文件的路径*/public static void getAudioFromVideo(String videoResourcesPath) {String fileName = videoResourcesPath.substring(videoResourcesPath.lastIndexOf("\\") + 1, videoResourcesPath.lastIndexOf("."));List<String> command = new ArrayList<>();command.add(ffmpeg);command.add("-i");command.add(videoResourcesPath);command.add(saveMediaPath + fileName + ".mp3");commandStart(command);}/*** 从视频中去除去音频并保存视频** @param videoResourcesPath 视频文件的路径*/public static void getVideoFromAudio(String videoResourcesPath) {List<String> command = new ArrayList<>();command.add(ffmpeg);command.add("-i");command.add(videoResourcesPath);command.add("-vcodec");command.add("copy");command.add("-an");command.add(saveMediaPath + videoResourcesPath.substring(videoResourcesPath.lastIndexOf("\\") + 1));commandStart(command);}/*** 无声视频+音频合并为一个视频* 若音频比视频长,画面停留在最后一帧,继续播放声音。** @param videoResourcesPath 视频文件的路径* @param audioResourcesPath 音频文件的路径*/public static void mergeSilent_VideoAudio(String videoResourcesPath, String audioResourcesPath) {List<String> command = new ArrayList<>();command.add(ffmpeg);command.add("-i");command.add(videoResourcesPath);command.add("-i");command.add(audioResourcesPath);command.add("-vcodec");command.add("copy");command.add("-acodec");command.add("copy");command.add(saveMediaPath + videoResourcesPath.substring(videoResourcesPath.lastIndexOf("\\") + 1));commandStart(command);}/*** 有声视频+音频合并为一个视频。* 若音频比视频长,画面停留在最后一帧,继续播放声音,* 若要以视频和音频两者时长短的为主,放开注解启用-shortest。** @param videoResourcesPath 视频文件的路径* @param audioResourcesPath 音频文件的路径*/public static void mergeVideoAudio(String videoResourcesPath, String audioResourcesPath) {List<String> command = new ArrayList<>();command.add(ffmpeg);command.add("-i");command.add(videoResourcesPath);command.add("-i");command.add(audioResourcesPath);command.add("-filter_complex");command.add("amix");command.add("-map");command.add("0:v");command.add("-map");command.add("0:a");command.add("-map");command.add("1:a");//-shortest会取视频或音频两者短的一个为准,多余部分则去除不合并//command.add("-shortest");command.add(saveMediaPath + videoResourcesPath.substring(videoResourcesPath.lastIndexOf("\\") + 1));commandStart(command);}/*** 多视频拼接合并** @param videoResourcesPathList 视频文件路径的List*/public static void mergeVideos(List<String> videoResourcesPathList) {//时间作为合并后的视频名String getdatatime = nowTime();//所有要合并的视频转换为ts格式存到videoList里List<String> videoList = new ArrayList<>();for (String video : videoResourcesPathList) {List<String> command = new ArrayList<>();command.add(ffmpeg);command.add("-i");command.add(video);command.add("-c");command.add("copy");command.add("-bsf:v");command.add("h264_mp4toannexb");command.add("-f");command.add("mpegts");String videoTempName = video.substring(video.lastIndexOf("\\") + 1, video.lastIndexOf(".")) + ".ts";command.add(tempMediaPath + videoTempName);commandStart(command);videoList.add(tempMediaPath + videoTempName);}List<String> command1 = new ArrayList<>();command1.add(ffmpeg);command1.add("-i");StringBuffer buffer = new StringBuffer("\"concat:");for (int i = 0; i < videoList.size(); i++) {buffer.append(videoList.get(i));if (i != videoList.size() - 1) {buffer.append("|");} else {buffer.append("\"");}}command1.add(String.valueOf(buffer));command1.add("-c");command1.add("copy");command1.add(saveMediaPath + "视频合并" + getdatatime + ".mp4");commandStart(command1);}/*** 多音频拼接合并为一个音频。** @param audioResourcesPathList 音频文件路径的List*/public static void mergeAudios(List<String> audioResourcesPathList) {//时间作为合并后的音频名String getdatatime = nowTime();List<String> command = new ArrayList<>();command.add(ffmpeg);command.add("-i");StringBuffer buffer = new StringBuffer("\"concat:");for (int i = 0; i < audioResourcesPathList.size(); i++) {buffer.append(audioResourcesPathList.get(i));if (i != audioResourcesPathList.size() - 1) {buffer.append("|");} else {buffer.append("\"");}}command.add(String.valueOf(buffer));command.add("-acodec");command.add("copy");command.add(saveMediaPath + "音频合并" + getdatatime + ".mp3");commandStart(command);}/*** 视频格式转换** @param videoResourcesPath 视频文件的路径* @param format             要转换为的格式*/public static void videoFormatConversion(String videoResourcesPath, String format) {String fileName = videoResourcesPath.substring(videoResourcesPath.lastIndexOf("\\") + 1, videoResourcesPath.lastIndexOf("."));List<String> command = new ArrayList<>();command.add(ffmpeg);command.add("-i");command.add(videoResourcesPath);command.add(saveMediaPath + fileName + "." + format);commandStart(command);}/*** 获取音频或视频信息** @param videoAudioResourcesPath 音频或视频文件的路径*/public static List<String> videoAudioInfo(String videoAudioResourcesPath) {List<String> command = new ArrayList<>();command.add(ffprobe);command.add("-i");command.add(videoAudioResourcesPath);//调用命令行获取视频信息String infoStr = getInfoStr(command);System.out.println(" ");String regexDuration = "Duration: (.*?), start: (.*?), bitrate: (\\d*) kb\\/s";String regexVideo = "Video: (.*?) tbr";String regexAudio = "Audio: (.*?), (.*?) Hz, (.*?) kb\\/s";List<String> list = new ArrayList<>();Pattern pattern = Pattern.compile(regexDuration);Matcher matcher = pattern.matcher(infoStr);if (matcher.find()) {list.add("视频/音频整体信息: ");list.add("视频/音频名称:" + videoAudioResourcesPath);list.add("开始时间:" + matcher.group(2));list.add("结束时间:" + matcher.group(1));list.add("比特率: " + matcher.group(3) + " kb/s");list.add("------------------------------------ ");}Pattern patternVideo = Pattern.compile(regexVideo);Matcher matcherVideo = patternVideo.matcher(infoStr);if (matcherVideo.find()) {String videoInfo = matcherVideo.group(1);String[] sp = videoInfo.split(",");list.add("视频流信息: ");list.add("视频编码格式: " + sp[0]);int ResolutionPosition = 2;if (sp[1].contains("(") && sp[2].contains(")")) {list.add("YUV: " + sp[1] + "," + sp[2]);ResolutionPosition = 3;} else if (sp[1].contains("(") && !sp[2].contains(")") && sp[3].contains(")")) {list.add("YUV: " + sp[1] + "," + sp[2] + "," + sp[3]);ResolutionPosition = 4;} else {list.add("YUV: " + sp[1]);}list.add("分辨率: " + sp[ResolutionPosition]);list.add("视频比特率: " + sp[ResolutionPosition + 1]);list.add("帧率: " + sp[ResolutionPosition + 2]);list.add("------------------------------------ ");}Pattern patternAudio = Pattern.compile(regexAudio);Matcher matcherAudio = patternAudio.matcher(infoStr);if (matcherAudio.find()) {list.add("音频流信息: ");list.add("音频编码格式: " + matcherAudio.group(1));list.add("采样率: " + matcherAudio.group(2) + " HZ");list.add("声道: " + matcherAudio.group(3).split(",")[0]);list.add("音频比特率: " + matcherAudio.group(3).split(",")[2] + " kb/s");}return list;}/*** 视频或音频剪切* 参考@link:https://zhuanlan.zhihu.com/p/27366331** @param videoAudioResourcesPath 视频或音频文件的路径* @param startTime               开始时间* @param endTime                 结束时间*/public static void cutVideoAudio(String videoAudioResourcesPath, String startTime, String endTime) {String fileName = videoAudioResourcesPath.substring(videoAudioResourcesPath.lastIndexOf("\\") + 1);//时间作为剪切后的视频名String getdatatime = nowTime();List<String> command = new ArrayList<>();command.add(ffmpeg);command.add("-ss");command.add(startTime);command.add("-t");command.add(calculationEndTime(startTime, endTime));command.add("-i");command.add(videoAudioResourcesPath);command.add("-c:v");command.add("libx264");command.add("-c:a");command.add("aac");command.add("-strict");command.add("experimental");command.add("-b:a");command.add("98k");command.add(saveMediaPath + "剪切视频" + getdatatime + fileName);commandStart(command);}/*** 视频裁剪大小尺寸(根据leftDistance和topDistance确定裁剪的起始点,再根据finallywidth和finallyHeight确定裁剪的宽和长)* 参考@link:https://www.cnblogs.com/yongfengnice/p/7095846.html*     @link:http://www.jq-school.com/show.aspx?id=737** @param videoAudioResourcesPath 视频文件的路径* @param finallyWidth            裁剪后最终视频的宽度* @param finallyHeight           裁剪后最终视频的高度* @param leftDistance            开始裁剪的视频左边到y轴的距离(视频左下角为原点)* @param topDistance             开始裁剪的视频上边到x轴的距离(视频左下角为原点)**/public static void cropVideoSize(String videoAudioResourcesPath, String finallyWidth, String finallyHeight, String leftDistance, String topDistance) {String fileName = videoAudioResourcesPath.substring(videoAudioResourcesPath.lastIndexOf("\\") + 1);//时间作为剪切后的视频名String getdatatime = nowTime();List<String> command = new ArrayList<>();command.add(ffmpeg);command.add("-i");command.add(videoAudioResourcesPath);command.add("-vf");//获取视频信息得到原始视频长、宽List<String> list = FfmpegUtils.videoAudioInfo(videoAudioResourcesPath);String resolution = list.stream().filter(v -> v.contains("分辨率")).findFirst().get();String sp[] = resolution.split("x");String originalWidth = sp[0].substring(sp[0].indexOf(":") + 1).trim();String originalHeight = sp[1].substring(0, 4).trim();Integer cropStartWidth = Integer.parseInt(originalWidth) - Integer.parseInt(leftDistance);Integer cropStartHeight = Integer.parseInt(originalHeight) - Integer.parseInt(topDistance);command.add("crop=" + finallyWidth + ":" + finallyHeight + ":" + cropStartWidth + ":" + cropStartHeight);command.add(saveMediaPath + "裁剪视频" + getdatatime + fileName);commandStart(command);}/*** 计算两个时间的时间差** @param startime 开始时间,如:00:01:09* @param endtime  结束时间,如:00:08:27* @return 返回xx:xx:xx形式,如:00:07:18*/public static String calculationEndTime(String startime, String endtime) {LocalTime timeStart = LocalTime.parse(startime);LocalTime timeEnd = LocalTime.parse(endtime);long hour = HOURS.between(timeStart, timeEnd);long minutes = MINUTES.between(timeStart, timeEnd);long seconds = SECONDS.between(timeStart, timeEnd);minutes = minutes > 59 ? minutes % 60 : minutes;String hourStr = hour < 10 ? "0" + hour : String.valueOf(hour);String minutesStr = minutes < 10 ? "0" + minutes : String.valueOf(minutes);long getSeconds = seconds - (hour * 60 + minutes) * 60;String secondsStr = getSeconds < 10 ? "0" + getSeconds : String.valueOf(getSeconds);return hourStr + ":" + minutesStr + ":" + secondsStr;}/*** 视频截图** @param videoResourcesPath 视频文件的路径* @param screenshotTime     截图的时间,如:00:01:06*/public static void videoScreenshot(String videoResourcesPath, String screenshotTime) {//时间作为截图后的视频名String getdatatime = nowTime();List<String> command = new ArrayList<>();command.add(ffmpeg);command.add("-ss");command.add(screenshotTime);command.add("-i");command.add(videoResourcesPath);command.add("-f");command.add("image2");String fileName = videoResourcesPath.substring(videoResourcesPath.lastIndexOf("\\") + 1, videoResourcesPath.lastIndexOf("."));command.add(picturMediaPath + fileName + getdatatime + ".jpg");commandStart(command);}/*** 整个视频截图** @param videoResourcesPath 视频文件的路径* @param fps                截图的速度。1则表示每秒截一张;0.1则表示每十秒一张;10则表示每秒截十张图片*/public static void videoAllScreenshot(String videoResourcesPath, String fps) {/*//时间作为截图后的视频名String getdatatime = nowTime();*/List<String> command = new ArrayList<>();command.add(ffmpeg);command.add("-i");command.add(videoResourcesPath);command.add("-vf");command.add("fps=" + fps);String fileName = videoResourcesPath.substring(videoResourcesPath.lastIndexOf("\\") + 1, videoResourcesPath.lastIndexOf("."));command.add(picturMediaPath + fileName + "%d" + ".jpg");commandStart(command);}/*** 多图片+音频合并为视频** @param pictureResourcesPath 图片文件路径(数字编号和后缀不要)。如:D:\ffmpegMedia\pictur\101-你也不必耿耿于怀1.jpg 和D:\ffmpegMedia\pictur\101-你也不必耿耿于怀2.jpg。只需传D:\ffmpegMedia\pictur\101-你也不必耿耿于怀* @param audioResourcesPath   音频文件的路径*  @param fps   帧率,每张图片的播放时间(数值越小则每张图停留的越长)。05.则两秒播放一张,1则一秒播放一张,10则一秒播放十张*/public static void pictureAudioMerge(String pictureResourcesPath, String audioResourcesPath,String fps) {//时间作为截图后的视频名String getdatatime = nowTime();List<String> command = new ArrayList<>();command.add(ffmpeg);command.add("-threads");command.add("2");command.add("-y");command.add("-r");//帧率command.add(fps);command.add("-i");command.add(pictureResourcesPath+"%d.jpg");command.add("-i");command.add(audioResourcesPath);command.add("-absf");command.add("aac_adtstoasc");//-shortest会取视频或音频两者短的一个为准,多余部分则去除不合并command.add("-shortest");String fileName = pictureResourcesPath.substring(pictureResourcesPath.lastIndexOf("\\") + 1);command.add(saveMediaPath +"视频合成"+ fileName + getdatatime + ".mp4");commandStart(command);}/*** 绘制音频波形图保存.jpg后缀可改为png** @param audioResourcesPath 音频文件的路径*/public static void audioWaveform(String audioResourcesPath) {List<String> command = new ArrayList<>();command.add(ffmpeg);command.add("-i");command.add(audioResourcesPath);command.add("-filter_complex");command.add("\"showwavespic=s=1280*240\"");command.add("-frames:v");command.add("1");String fileName = audioResourcesPath.substring(audioResourcesPath.lastIndexOf("\\") + 1, audioResourcesPath.lastIndexOf("."));//jpg可换为pngcommand.add(saveMediaPath + fileName + fileName + ".jpg");commandStart(command);}/*** 两个音频混缩合并为一个音频。* 音量参考:@link:https://blog.csdn.net/sinat_14826983/article/details/82975561** @param audioResourcesPath1 音频1文件路径* @param audioResourcesPath1 音频2文件路径的*/public static void mergeAudios(String audioResourcesPath1, String audioResourcesPath2) {//时间作为混缩后的音频名String getdatatime = nowTime();List<String> command = new ArrayList<>();command.add(ffmpeg);command.add("-i");command.add(audioResourcesPath1);command.add("-i");command.add(audioResourcesPath2);command.add("-filter_complex");command.add("amix=inputs=2:duration=longest");command.add(saveMediaPath + "音频混缩" + getdatatime + ".mp3");commandStart(command);}/*** 两个音频混缩合并为一个音频的不同声道(即一只耳机播放一个音频)。* 声道参考:@link:https://www.itranslater.com/qa/details/2583879740000044032** @param audioResourcesPath1 音频1文件路径* @param audioResourcesPath1 音频2文件路径的*/public static void mergeAudiosSoundtrack(String audioResourcesPath1, String audioResourcesPath2) {//时间作为混缩后的音频名String getdatatime = nowTime();List<String> command = new ArrayList<>();command.add(ffmpeg);command.add("-i");command.add(audioResourcesPath1);command.add("-i");command.add(audioResourcesPath2);command.add("-filter_complex");command.add("\"amerge=inputs=2,pan=stereo|c0<c0+c1|c1<c2+c3\"");command.add(saveMediaPath + "音频混缩" + getdatatime + ".mp3");commandStart(command);}/*** 获取当前时间,用于作为文件名*/public static String nowTime() {DateTimeFormatter f3 = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss");LocalDate nowdata = LocalDate.now();LocalTime nowTime = LocalTime.now();return nowdata.atTime(nowTime).format(f3);}
}

测试

import utils.FfmpegUtils;
import java.io.IOException;
import java.util.*;public class Test {public static void main(String[] args) throws IOException {//视频播放FfmpegUtils.playVideoAudio("D:\\16-这几句真假声转换太好听了.mp4");//视频播放并指定循环次数FfmpegUtils.playVideoAudio("D:\\16-这几句真假声转换太好听了.mp4",1);//视频播放并指定宽高和循环次数FfmpegUtils.playVideoAudio("D:\\16-这几句真假声转换太好听了.mp4",400,700,1);//从视频中提取音频为mp3FfmpegUtils.getAudioFromVideo("D:\\16-这几句真假声转换太好听了.mp4");//从视频中提取视频为无声视频FfmpegUtils.getVideoFromAudio("D:\\16-这几句真假声转换太好听了.mp4");//无声视频+音频合并FfmpegUtils.mergeSilent_VideoAudio("D:\\507-#网愈云故事收藏馆.mp4","D:\\mp3\\16-这几句真假声转换太好听了.mp3");//格式转换FfmpegUtils.videoFormatConversion("D:\\507-#网愈云故事收藏馆.mp4","flv");//多视频拼接合并为一个mp4格式视频List<String> video = new ArrayList<>();video.add("D:\\16-这几句真假声转换太好听了.mp4");video.add("D:\\507-#网愈云故事收藏馆.mp4");video.add("D:\\101-你也不必耿耿于怀.mp4");FfmpegUtils.mergeVideos(video);//获取音频或视频信息List<String> list = FfmpegUtils.videoAudioInfo("D:\\ffmpegMedia\\16-这几句真假声转换太好听了.mp3");list.forEach(v -> System.out.println(v));//剪切视频或音频,startTime开始时间,结束时间FfmpegUtils.cutVideoAudio("D:\\苏打绿带我走.mp4","00:00:00","00:01:05");//裁剪视频尺寸大小FfmpegUtils.cropVideoSize("D:\\张国荣.mp4", "600", "600", "720", "940");//有声视频+音频合并FfmpegUtils.mergeVideoAudio("D:\\507-#网愈云故事收藏馆.mp4","D:\\ffmpegMedia\\16-这几句真假声转换太好听了.mp3");//视频截图,screenshotTime是截图的时间FfmpegUtils.videoScreenshot("D:\\101-你也不必耿耿于怀.mp4","00:00:05");//视频完全截图,fps是截图的速度即多少秒截一张图FfmpegUtils.videoAllScreenshot("D:\\101-你也不必耿耿于怀.mp4","1");//多图片+音频合并为视频。05.则两秒播放一张,1则一秒播放一张,10则一秒播放十张(数值越小则每张图停留的越长)FfmpegUtils.pictureAudioMerge("D:\\ffmpegMedia\\pictur\\101-你也不必耿耿于怀","D:\\ffmpegMedia\\101-你也不必耿耿于怀.mp3","0.5");//多音频拼接合并为一个mp3格式视频List<String> audio = new ArrayList<>();audio.add("D:\\ffmpegMedia\\16-这几句真假声转换太好听了.mp3");audio.add("D:\\ffmpegMedia\\忽然之间.mp3");audio.add("D:\\ffmpegMedia\\天空之城-李志.mp3");FfmpegUtils.mergeAudios(audio);//绘制音频波形图保存FfmpegUtils.audioWaveform("D:\\ffmpegMedia\\16-这几句真假声转换太好听了.mp3");//两个音频混缩合并为一个音频FfmpegUtils.mergeAudios("D:\\ffmpegMedia\\16-这几句真假声转换太好听了.mp3","D:\\ffmpegMedia\\天空之城-李志.mp3");//两个音频混缩合并为一个音频的不同声道(即一只耳机播放一个音频)。FfmpegUtils.mergeAudiosSoundtrack("D:\\ffmpegMedia\\16-这几句真假声转换太好听了.mp3","D:\\ffmpegMedia\\天空之城-李志.mp3");}
}

转载地址:https://blog.csdn.net/qq_33697094/article/details/112847624

Java使用ffmpeg进行视频格式转换、音视频合并、播放、截图相关推荐

  1. 视频格式转换器之视频格式在线转换详细教程 1

    视频格式转换器相信大家都是知道的,在日常工作和学习中,都是需要观看视频文件的,但是视频文件有众多的视频格式:MP4.MKV.MOV.AVI.SWF.FLV.WEBM等等,每个视频格式的画质以及设备兼容 ...

  2. 【PC工具】在线格式转换工具,视频格式转换,视频转gif工具

    上次在社区发文章,得知文章编辑器终于支持gif格式的动图了,但得到gif的动图需要将mp4格式的视频进行格式转换,于是便找到了这个在线工具.这年头方便好用是第一位的,功能差不多的情况下在线工具优于绿色 ...

  3. macbook视频格式转换_mac视频格式转换怎么操作?如何将视频转换成mac能播放的格式?...

    mac 视频格式转换怎么操作?如何将视频转换成 mac 能播放的格式? 别以为 mac 只是系统和咱们普通的电脑不一样,实际上,在操作中,它还有很多的不一样. 比如说咱们 Windows 系统中常见的 ...

  4. linux下视频格式转换与视频合并

    熟悉Windows的朋友应该知道,Windows下的视频格式转换软件与合并视频软件不计其数,刚接触Linux的朋友也许会抱怨Linux下没有强大的视频软件,完成视频播放.转化视频格式.合并视频等功能. ...

  5. Java使用ffmpeg进行音频格式转换

    ffmpeg相关文章网址(用于记录一些好的文章地址~) ffmpeg命令详解 https://blog.csdn.net/zzcchunter/article/details/68060989 jav ...

  6. html5中加入视频格式,HTML5音视频格式video和audio

    html5音频和视频使用详解. 一.html5视频 以前,大多数视频是通过插件(比如 Flash)来显示的,然而,并非所有浏览器都拥有同样的插件 现在,HTML5 规定了一种通过 video 元素来包 ...

  7. 【JAVA】JAVA使用ffmpeg进行视频格式转换以及截图

    JAVA 处理视频文件,需要用到 ffmpeg  这个工具.不需要依赖jar包.无论是在windows服务器还是linux服务器,想要使用 ffmpeg 都需要先安装. 附上Linux下  *.tar ...

  8. ffmpeg 视频格式转换和宽高转换 制作自己想要的数据格式

    ffmpeg 视频格式转换和宽高转换 制作自己想要的数据格式 命令如下: ffmpeg -y -i Titanic.mkv -s 640*480 out.h264 运行效果: 一般的 使用 ffmpe ...

  9. 有什么免费的视频格式转换工具?快试试这4款,堪称“良心”工具

    无论是在娱乐.学习还是工作中,我们都有离线观看视频的需求,然而有些视频格式系统自带的播放软件不支持,这个时候就需要转换视频格式,有什么免费的视频格式转换工具呢?下面给大家分享4款. 我们要分享的第一款 ...

最新文章

  1. BZOJ 2152 「国家集训队」聪聪可可(点分治)【BZOJ计划】
  2. Tomcat 与 Resin PK大战
  3. cambridge sharing note 1
  4. leetcode刷题实录:2
  5. 学而思的python课怎么样_有在用学而思网校的同学觉得孙墨漪老师怎么样?报她的课值得吗?...
  6. 十九、Pytorch中的数据加载
  7. python博客项目评论_Python 爬虫入门——小项目实战(自动私信博客园某篇博客下的评论人,随机发送一条笑话,完整代码在博文最后)...
  8. redis查询key的数量
  9. 常引用、常对象和对象的常成员
  10. systemd(CentOS7)启动zookeeper
  11. 数电-汽车尾灯控制电路设计
  12. 【H3CTE认证和HCIE认证一样吗?】
  13. 长短期记忆人工神经网络(LSTM)网络学习资料
  14. ApkScan-PKID查壳工具+脱壳(搬运)
  15. saltstack的NETAPI接口详讲
  16. response响应讲解
  17. 编程要了解的基础知识
  18. 麻雀算法SSA,优化VMD,适应度函数为最小包络熵,包含MATLAB源代码,直接复制粘贴!
  19. 02-网络为什么要分层
  20. ElasticSearch[03]SpringData集成ElasticSearch

热门文章

  1. c语言错误c4047,c语言错误 apos;int apos; differs in levels of indirection from apos;int *apos;...
  2. 数据结构学习笔记(6)——图
  3. 渗流分析 matlab,基于matlab的边坡虹吸排水渗流场分析
  4. 支持外链的免费相册地址集合
  5. 注册表项目不能删除的解决方案
  6. 影视级跨平台视频制作技术的落地实践
  7. 美国推出世界首款可自动调音吉他机器人
  8. 市场调研-全球与中国Mini-USB数据线市场现状及未来发展趋势
  9. 写过Flex的非Flex人士
  10. 在ubuntu16.04上运行ROS获取D415深度图像