android端使用ffmpeg给视频添加图片水印
2017-04-18 本文已影响3784人
书柜里的松鼠
直接举个栗子:
public static String[] addwaterMark(String imageUrl,String videoUrl,String outputUrl){
String[] commands = new String[9];
commands[0] = "ffmpeg";
//输入
commands[1] = "-i";
commands[2] = videoUrl;
//水印
commands[3] = "-i";
commands[4] = imageUrl;//此处的图片地址换成带透明通道的视频就可以合成动态视频遮罩。
commands[5] = "-filter_complex";
commands[6] = "overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2";
//覆盖输出
commands[7] = "-y";//直接覆盖输出文件
//输出文件
commands[8] = outputUrl;
return commands;
}
private void makeVideo(){
final String[] _commands=addwaterMark(imageUrl,videoUrl,outputUrl);
Runnable compoundRun=new Runnable() {
@Override
public void run() {
FFmpegKit.execute(_commands, new FFmpegKit.KitInterface() {
@Override
public void onStart() {
Log.d("FFmpegLog LOGCAT","FFmpeg 命令行开始执行了...");
}
@Override
public void onProgress(int progress) {
Log.d("FFmpegLog LOGCAT","done com"+"FFmpeg 命令行执行进度..."+progress);
}
@Override
public void onEnd(int result) {
Log.d("FFmpegLog LOGCAT","FFmpeg 命令行执行完成...");
}
});
}
};
ThreadPoolUtils.execute(compoundRun);
}
addwaterMark()中的videoUrl是原始文件地址,imageUrl是水印图片地址,outputUrl是视频输出地址。
-filter_complex 参数是表示使用混合滤镜把图片叠加到视频上。
overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2 是将图片居中,当然这里的具体位置可以自己调。
一般来说,加个水印就这样就可以了。
然而,实际中我们总是需要来点大小的调整。
使用scale参数可以调整水印大小。
像这样
String[] commands = new String[9];
commands[0] = "ffmpeg";
//输入
commands[1] = "-i";
commands[2] = videoUrl;
//水印
commands[3] = "-i";
commands[4] = imageUrl;//此处的图片地址换成带透明通道的视频就可以合成动态视频遮罩。
commands[5] = "-filter_complex";
commands[6] = "[1:v]scale=100:200[s];[0:v][s]overlay=0:0";
//覆盖输出
commands[7] = "-y";//直接覆盖输出文件
//输出文件
commands[8] = outputUrl;
return commands;
好,现在你可以随意添加任意大小位置的水印了。
那么,能不能再给力一点?我们使用两张图片叠加双重水印。
命令行格式如下:
String[] commands = new String[11];
commands[0] = "ffmpeg";
//输入
commands[1] = "-i";
commands[2] = videoUrl;
//水印
commands[3] = "-i";
commands[4] = image1;
commands[5] = "-i";
commands[6] = image2;
commands[7] = "-filter_complex";
commands[8] = "[1:v]scale=100:100[img1];[2:v]scale=1280:720[img2];[0:v][img1]overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2[bkg];[bkg][img2]overlay=0:0";
//覆盖输出
commands[9] = "-y";//直接覆盖输出文件
//输出文件
commands[10] = outputUrl;
return commands;
附1:
用来当水印的图片也支持gif格式,那么gif要在整个视频播放阶段循环的话就请使用-ignore_loop参数。这个参数的值为1则忽略gif文件本身的循环设置,为0的话则使用文件本身的设置。
比如这样:
String[] commands = new String[11];
commands[0] = "ffmpeg";
//输入
commands[1] = "-i";
commands[2] = videoUrl;
//水印
commands[3] = "-ignore_loop";
commands[3] = "0";
commands[3] = "-i";
commands[4] = image1.gif;
commands[5] = "-i";
commands[6] = image2;
commands[7] = "-filter_complex";
commands[8] = "[1:v]scale=100:100[img1];[2:v]scale=1280:720[img2];[0:v][img1]overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2[bkg];[bkg][img2]overlay=0:0";
//覆盖输出
commands[9] = "-y";//直接覆盖输出文件
//输出文件
commands[10] = outputUrl;
return commands;
附2:
以上命令也适用与透明视频的叠加。把图片地址换成带透明通道的视频文件的地址就好了。(带透明通道的视频素材网上可以下载到很多,一般都是mov格式)(然而不知道怎么像gif那样设置循环,叠加的视频仅播放一次。有知道的同学分享下经验呗。)
附3:
ffmpeg的命令行参数除了头尾,中间各组的顺序是无关的,但是各组参数内部不能放错。比如属于设置滤镜的参数穿插到了输出里了的话就会出错。
相关:
在android studio中使用FFmpeg
FFmpeg命令行语法之-filter_complex
使用ffmpeg添加文字水印一直没有成功,打包了freetype也没有搞定。暂时只好把文字生成为png图片凑合一下。有没有小伙伴提供下思路或者范例的?