1. 前言
FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。
2.1 实现格式转换功能
该方法就设置了一个入参,即文件路径。参数ffmpegPath是@value引入的yml配置,如下图
指向的路径下放入FFmpeg的.exe文件即可。
@Value("${ffmpeg.path}")
String ffmpegPath;
public String transCoding(String path) throws IOException {
String ffmpegExePath = new ClassPathResource(ffmpegPath+"/ffmpeg.exe").getAbsolutePath();
ArrayList<String> command = new ArrayList<>();
command.add(ffmpegExePath);
command.add("-i");
command.add(path);
command.add("-vcodec");
command.add("copy");
command.add("-f");
command.add("mpegts");
String s = "E:\\data\\split\\" + IdUtil.simpleUUID() + ".mp4";
command.add(s);
// 执行操作
ProcessBuilder builder = new ProcessBuilder();
builder.command(command);
builder.redirectErrorStream(true);
Process process = builder.start();
return s;
}
2.2 实现视频剪辑
public String videoSpit(String path, String startTime, String duration) throws IOException {
int i = Integer.parseInt(startTime) / 1000;
int i1 = Integer.parseInt(duration) / 1000;
String ffmpegExePath = new ClassPathResource(ffmpegPath +"/ffmpeg.exe").getAbsolutePath();
List<String> command = new ArrayList<>();
command.add(ffmpegExePath);
command.add("-ss");
command.add(String.valueOf(i));
command.add("-t");
command.add(String.valueOf(i1));
command.add("-accurate_seek");
command.add("-i");
if (!FileUtil.file(path).isFile()) {
return "文件不存在,请检查!!";
}
command.add(path);
command.add("-codec");
command.add("copy");
command.add("-avoid_negative_ts");
command.add("1");
String s = IdUtil.simpleUUID();
//本地开发写死路径
String substring = path.substring(path.lastIndexOf("."));
String e1 = "E:\\data\\split\\" + s + path.substring(path.lastIndexOf("."));
StringBuilder stringBuffer = new StringBuilder();
//业务需求,判断是否为mp4,如不需要可以去掉
if (!"mp4".equals(substring)) {
String s1 = transCoding(e1);
command.add(s1);
stringBuffer.append(s1);
}else {
command.add(e1);
stringBuffer.append(e1);
}
try {
System.out.println(command);
ProcessBuilder builder = new ProcessBuilder();
builder.command(command);
//正常信息和错误信息合并输出
builder.redirectErrorStream(true);
//开始执行命令
Process process = builder.start();
//如果你想获取到执行完后的信息,那么下面的代码也是需要的
StringBuilder sbf = new StringBuilder();
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((line = br.readLine()) != null) {
sbf.append(line);
sbf.append(" ");
}
String resultInfo = sbf.toString();
System.out.println(resultInfo);
System.out.println(stringBuffer);
return stringBuffer.toString();
} catch (IOException e) {
e.printStackTrace();
}
return "操作失败";
}
path 是文件路径,startTime是开始时间,duration是持续时间,我这里传入的时间是ms,所以先转换成s。方便FFmpeg处理
2.3 实现对指定区域的裁剪并切割
public void spit(String filePath, Integer startTime, String location, String continuous, Integer number) throws IOException {
ArrayList<String> command = new ArrayList<>();
DecimalFormat df = new DecimalFormat("0.00");
StringBuilder stringBuffer = new StringBuilder();
for (int i = 0; i < number; i++) {
command.add("E:\\data\\ffmpeg.exe");
command.add("-ss");
String format = df.format((float) i / number + startTime);
System.out.println("开始时间" + format);
command.add(String.valueOf(format));
command.add("-i");
command.add(filePath);
command.add("-strict");
command.add("-2");
command.add("-vf");
command.add(location);
command.add("-t");
command.add(continuous);
String s = "E:\\data\\spit-test\\2s\\" + format + ".mp4";
System.out.println(s);
command.add(s);
ProcessBuilder builder = new ProcessBuilder();
builder.command(command);
System.out.println(command);
builder.redirectErrorStream(true);
Process process = builder.start();
command.removeAll(command);
StringBuilder sbf = new StringBuilder();
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((line = br.readLine()) != null) {
sbf.append(line);
sbf.append(" ");
}
String resultInfo = sbf.toString();
System.out.println(resultInfo);
System.out.println(stringBuffer);
}
}
filePath 文件路径
startTime 开始时间(单位/s)
location 裁剪的位置,格式如:crop=w=100:h=100:x=12:y=34 ,其中w和h指的是裁剪完的帧宽度和帧高度,x和y指裁剪的坐标点,裁剪时会按照该点坐标往右下裁剪。
continuous 持续时间
number 颗粒度 该参数是业务为需求定制,因为我需要按照业务会把视频以0.1s、0.01s切片,则此参数影响for循环次数,根据具体业务修改
截取前:
截取后:
版权声明:本文为qq_34252622原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。