明天你是否会想起 坐在你旁边的小弟 明天你是否还惦记 内存溢出的虚拟机
回想起粉笔的点点滴滴 我永远都难以忘记
是否能再给契机 让你我再相遇
致 chalk 、 我亲爱的豪哥
我转过我的脸 看不到你的眼 之前的消息你都没发现
方式一
package com.gluoh.file.ffmpeg;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MergeFile {
/**
* 明天你是否会想起 坐在你旁边的小弟 明天你是否还惦记 内存溢出的虚拟机
* 回想起粉笔的点点滴滴 我永远都难以忘记
* 是否能再给契机 让你我再相遇
*
* 致 chalk 、 我亲爱的豪哥
*
* 我转过我的脸 看不到你的眼 之前的消息你都没发现
*
* **List fromVideoFileList 需要合并的多视频url地址以List存放**
* **String ffmpeg 此处是ffmpeg 配置地址,可写死如“E:/ffmpeg/bin/ffmpeg.exe”**
* **String NewfilePath 合并后的视频存放地址,如:E:/mergevideo.mp4***
*/
public static void convetor(List fromVideoFileList, String ffmpeg,
String NewfilePath) throws IOException {
new Thread(
() -> {
try {
List voidTS = new ArrayList<>();
Process process = null;
ProcessBuilder builder = null;
List command = null;
for (int i = 0; i < fromVideoFileList.size(); i++) {
String fromVideoFile = fromVideoFileList.get(i);
command = new ArrayList();
command.add(ffmpeg);
command.add("-y");
command.add("-i");
command.add(fromVideoFile);
command.add("-vcodec");
command.add("copy");
command.add("-bsf:v");
command.add("h264_mp4toannexb");
command.add("-f");
command.add("mpegts");
command.add(fromVideoFile.substring(0,
fromVideoFile.lastIndexOf(".")) + ".ts");
builder = new ProcessBuilder(command);
voidTS.add(fromVideoFile.substring(0,
fromVideoFile.lastIndexOf("."))
+ ".ts");
try {
process = builder.start();
InputStream errorStream = process
.getErrorStream();
InputStreamReader inputStreamReader = new InputStreamReader(
errorStream);
BufferedReader br = new BufferedReader(
inputStreamReader);
String line = "";
StringBuffer sb = new StringBuffer();
while ((line = br.readLine()) != null) {
sb.append(line);
}
String regexDuration = "Duration: (.*?), start: (.*?), bitrate: (\\d*) kb\\/s";
Pattern pattern = Pattern
.compile(regexDuration);
Matcher m = pattern.matcher(sb.toString());
/* */
System.out.println(sb.toString());
br.close();
inputStreamReader.close();
errorStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
List dos = new ArrayList<>();
StringBuffer tsPath = new StringBuffer();
tsPath.append(ffmpeg);
tsPath.append(" -i ");
tsPath.append("concat:");
for (int t = 0; t < voidTS.size(); t++) {
if (t != voidTS.size() - 1) {
tsPath.append(voidTS.get(t) + "|");
} else {
tsPath.append(voidTS.get(t));
}
}
tsPath.append(" -vcodec ");
tsPath.append(" copy ");
tsPath.append(" -bsf:a ");
tsPath.append(" aac_adtstoasc ");
tsPath.append(" -movflags ");
tsPath.append(" +faststart ");
tsPath.append(NewfilePath);
Process pr = Runtime.getRuntime().exec(
tsPath.toString());
process.getInputStream();
pr.getOutputStream().close();
pr.getInputStream().close();
pr.getErrorStream().close();
try {
pr.waitFor();
Thread.sleep(1000);
pr.destroy();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//删除生成的ts文件
for (String filePath : voidTS) {
File file = new File(filePath);
file.delete();
pr.destroy();
}
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
public static void main(String[] args) throws IOException {
String ffmpeg = "E:\\dev-env\\ffmpeg\\bin\\ffmpeg.exe";
String NewfilePath = "E:\\mergevideo.mp4";
List fromVideoFileList = new ArrayList();
fromVideoFileList.add("E:\\01.mp4");
fromVideoFileList.add("E:\\02.mp4");
convetor(fromVideoFileList, ffmpeg, NewfilePath);
}
}
方式二-使用concat分离器合成视屏
@ApiOperation(value = "视频合并", notes = "视频合并", response = Result.class)
@PostMapping("/concatVideo")
public Result concatVideo(
@ApiParam(name = "files", value = "文件", required = true)
@RequestParam("files") MultipartFile[] files) {
List
import java.io.File;
import java.util.List;
/**
* @author xiaoqiang
* @Description 视频第一帧处理工具
* @date 2019/5/29 10:21
*/
public class FirstFrameUtil {
//windows
//private static String FFMPEG_PATH = "D:/soft/ffmpeg/bin/ffmpeg.exe";
//centos
private static String FFMPEG_PATH = "/usr/local/bin/ffmpeg";
/**
* FFmpeg
* @param veidoPath
* @return
*/
public static boolean processImg(String veidoPath) {
File file = new File(veidoPath);
if (!file.exists()) {
System.err.println("路径[" + veidoPath + "]对应的视频文件不存在!");
return false;
}
List commands = new java.util.ArrayList();
commands.add(FFMPEG_PATH);
commands.add("-i");
commands.add(veidoPath);
commands.add("-y");
commands.add("-f");
commands.add("image2");
commands.add("-ss");
// 这个参数是设置截取视频多少秒时的画面
commands.add("1");
// commands.add("-t");
// commands.add("0.001");
commands.add("-s");
commands.add("700x525");
commands.add(veidoPath.substring(0, veidoPath.lastIndexOf("."))
.replaceFirst("vedio", "file") + ".jpg");
try {
ProcessBuilder builder = new ProcessBuilder();
builder.command(commands);
builder.start();
System.out.println("截取成功");
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static boolean video(String outPath) {
File file = new File("/home/ffmpeg/file.txt");
if (!file.exists()) {
System.err.println("文件不存在!");
return false;
}
List commands = new java.util.ArrayList();
commands.add(FFMPEG_PATH);
commands.add("-y");//覆盖元视屏
commands.add("-f");
commands.add("concat");
commands.add("-safe");
commands.add("0");
commands.add("-i");
commands.add("/home/ffmpeg/file.txt");
commands.add("-c");
commands.add("copy");
commands.add(outPath);
try {
ProcessBuilder builder = new ProcessBuilder();
builder.command(commands);
builder.start();
System.out.println("合成功");
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}