在JAVA中使用FFMPEG编辑绿幕视频的背景,添加图标
准备工作
使用Maven引入FFMPEG相关依赖
此处使用bytedeco的javacv包
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.5.6</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>ffmpeg-platform</artifactId>
<version>4.4-1.5.6</version>
</dependency>
安装一个FFMPEG,用于调试命令
官方下载
下载解压后把bin目录添加到环境变量Path中,之后即可在cmd中使用。
完成后可通过 ffmpeg -version 指令检测
编写FFMPEG命令
在此分享我自己使用的命令
替换绿幕背景
该命令的目的是用default_bg.png作为一个绿幕视频video.mp4的背景
ffmpeg -loop 1 -i default_bg.png -i video.mp4
-filter_complex "[1:v]chromakey=0x70de77:0.1:0.01[ckout];[0:v][ckout]overlay=0:0:shortest=1,format=yuv420p"
-c:a copy -y output.mp4
在此解释一下
- -loop 1 启用循环,因为背景图片只有一帧,将它设置为直到视频流结束不停循环这一震。
- -i default_bg.png 设置第1个输入,背景图的default_bg.png,同时也是loop的目标
- -i video.mp4 设置第2个输入,视频的video.mp4。
- -filter_complex FFMPGE的滤镜配置标签
[1:v]chromakey=0x70de77:0.1:0.01[ckout]; [1:v]第1个(从0开始)输入的视频(video),chromakey=0x70de77:0.1:0.01将颜色0x70de77转化为透明,相似度0.1,模糊度0.01;相似度和模糊度可根据自己需求调整。[ckout]将该滤镜的输出设置为[ckout]变量 - [0:v][ckout]overlay=0:0:shortest=1,format=yuv420p;将[ckout]流放到第0个输出的视频流上,偏移位置为x:0,y:0,输出格式为yuv420p。
- -c:a copy -y output.mp4 解码音频 输出为output.mp4
###添加图标
ffmpeg -i logo.mp4 -loop 1 -i logo.png
-filter_complex "[1]scale=iw*5:-1 [overlay];[0:v][overlay]overlay=50:100:shortest=1,format=yuv420p"
-c:a copy -y output.mp4
大体和上一段命令相似,介绍不一样的部分
scale是用于缩放,本命令中是指将第[1]个输出缩放到5倍。iw的意思是输入的width,-1意思是保持原比例自动缩放。
JAVA程序
主要逻辑是通过org.bytedeco.javacpp.Loader装载ffmpeg之后运行刚才的指令。demo如下
import org.bytedeco.javacpp.Loader;
public static void executeFFMPEG(List<String> command) {
try {
String join = String.join(" ", command);
System.out.println(join);
ProcessBuilder process = new ProcessBuilder(command);
process.inheritIO().start().waitFor();
} catch (Exception e) {
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void setBackground(String imagePath, String videoPath, String outputPath)
throws Exception {
List<String> command = new ArrayList();
// 获取JavaCV中的ffmpeg本地库的调用路径
String ffmpeg = Loader.load(org.bytedeco.ffmpeg.ffmpeg.class);
command.add(ffmpeg);
command.add("-loop");
command.add("1");
command.add("-i");
command.add(imagePath);
command.add("-i");
command.add(videoPath);
command.add("-filter_complex");
//chromakey去绿幕 overlay叠放 -c:a 解码音频
command.add("[1:v]chromakey=0x70de77:0.1:0.01[ckout];[0:v][ckout]overlay=0:0:shortest=1,format=yuv420p");
command.add("-c:a");
command.add("copy");
command.add(outputPath);
executeFFMPEG(command);
}
public static void addLogo(String logoPath, String videoPath, int scale, int left, int top, String outputPath)
throws Exception {
List<String> command = new ArrayList();
// 获取JavaCV中的ffmpeg本地库的调用路径
String ffmpeg = Loader.load(org.bytedeco.ffmpeg.ffmpeg.class);
command.add(ffmpeg);
command.add("-i");
command.add(videoPath);
command.add("-loop");
command.add("1");
command.add("-i");
command.add(logoPath);
command.add("-filter_complex");
// scale缩放 overlay叠放 -c:a 解码音频
command.add("[1]scale=iw*" + scale + ":-1 [overlay];[0:v][overlay]overlay=" + left + ":" + top+ ":shortest=1,format=yuv420p");
command.add("-c:a");
command.add("copy");
command.add(outputPath);
executeFFMPEG(command);
}