使用ffmepg工具,这里就不过多阐述,详细的可查看,我以前的博客。
准备20张图片,我这里的二十张图片都是加了时间水印的图片(你也可以找不一样的图片,能看出切换的效果就行)。
功能:需要把20张图片合成视频
思路:首先我们存放在本地的图片,一般都是按日期存放的,例如20190515165200.jpg,如果我们要使用ffmepg,合成视频,就需要新创建一个文件夹temp,并把以前的图片复制到temp文件下,注意,一定要满足正则,不然,ffmepeg是无法识别的
注意下面的图片名称格式:都是满足正则表示%2d,因为视频的合成,会根据排序索引一直到最后,如果中间有中断,视频也会终止合成。
这句话如何理解?
我们通过下面的图片发现名称前面的名称是一直+1的,假设我们把05改成22,说明视频到图片04就停止勒,合成的视频指挥包含0-4的图片。
2.多个图片合成视频代码
-
package com.qihui.qxj.services.system;
-
-
import java.io.IOException;
-
import java.io.InputStream;
-
import java.util.ArrayList;
-
import java.util.List;
-
-
import org.junit.Test;
-
-
public
class
Test1 {
-
-
/**
-
* 把图片拼接成视频,这里取20张图片,生成10秒的视频
-
*/
-
@
Test
-
public
void
test3(
) {
-
long startTime =System.currentTimeMillis();
-
List commend =
new ArrayList();
-
commend.
add(
"c:/bin/ffmpeg.exe");
-
//以1fps读入
-
commend.
add(
"-r");
-
commend.
add(
"4");
-
//-threads 2 以两个线程进行运行, 加快处理的速度。
-
commend.
add(
"-threads");
-
commend.
add(
"2");
-
commend.
add(
"-f");
-
commend.
add(
"image2");
-
commend.
add(
"-i");
-
commend.
add(
"d:/project/destimg/40/test/%2d.jpg");
-
commend.
add(
"-vcodec");
-
commend.
add(
"libx264");
-
//-y 对输出文件进行覆盖
-
commend.
add(
"-y");
-
//-r 5 fps设置为5帧/秒(不同位置有不同含义) %2d标识图片文件的正则
-
commend.
add(
"-r");
-
commend.
add(
"10");
-
commend.
add(
"d:/out.mp4");
-
start(commend);
-
long endTime =System.currentTimeMillis();
-
System.
out.println((endTime-startTime));
-
}
-
-
-
private void start(List commend) {
-
Process p =
null;
-
try {
-
ProcessBuilder builder =
new ProcessBuilder(commend);
-
builder.command(commend);
-
p = builder.start();
-
p.getOutputStream().close();
-
doWaitFor(p);
-
p.destroy();
-
}
catch (Exception e) {
-
PrintCatchErrorMsg.Print(e,
"Part",
"getRSTPPicture.catch",
"Exception");
-
p.destroy();
-
}
-
}
-
-
-
public static int doWaitFor(Process p) {
-
InputStream
in =
null;
-
InputStream err =
null;
-
int exitValue =
-1;
-
-
try {
-
in = p.getInputStream();
-
err = p.getErrorStream();
-
boolean finished =
false;
-
-
while(!finished) {
-
try {
-
Character c;
-
while(
in.available() >
0) {
-
c =
new Character((
char)
in.read());
-
System.
out.print(c);
-
}
-
-
while(err.available() >
0) {
-
c =
new Character((
char)err.read());
-
System.
out.print(c);
-
}
-
-
exitValue = p.exitValue();
-
finished =
true;
-
}
catch (IllegalThreadStateException var19) {
-
Thread.currentThread();
-
Thread.sleep(
500L);
-
}
-
}
-
}
catch (Exception var20) {
-
}
finally {
-
try {
-
if (
in !=
null) {
-
in.close();
-
}
-
}
catch (IOException var18) {
-
}
-
-
if (err !=
null) {
-
try {
-
err.close();
-
}
catch (IOException var17) {
-
}
-
}
-
-
}
-
-
return exitValue;
-
}
-
}
-r在不同位置,产生的意思不一样,-r放在-i前,表示输入,这里我设置的4,表示1秒4帧,20个图片,也就是5秒。
3.多个图片合成视频并打上图片水印
-
/**
-
* 把图片拼接成视频,这里取20张图片,生成10秒的视频
-
*/
-
@
Test
-
public
void
test3(
) {
-
long startTime =System.currentTimeMillis();
-
List commend =
new ArrayList();
-
commend.
add(
"c:/bin/ffmpeg.exe");
-
//以1fps读入
-
commend.
add(
"-r");
-
commend.
add(
"4");
-
//-threads 2 以两个线程进行运行, 加快处理的速度。
-
commend.
add(
"-threads");
-
commend.
add(
"2");
-
commend.
add(
"-f");
-
commend.
add(
"image2");
-
commend.
add(
"-i");
-
commend.
add(
"d:/project/destimg/40/test1/%2d.jpg");
-
commend.
add(
"-i");
-
commend.
add(
"d:/1557906953.jpg");
-
commend.
add(
"-filter_complex");
-
commend.
add((
new StringBuilder(
"[1:v]scale=150:150[s];[0:v][s]overlay=")).append(
1800).append(
":").append(
900)
-
.toString());
-
-
commend.
add(
"-vcodec");
-
commend.
add(
"libx264");
-
//-y 对输出文件进行覆盖
-
commend.
add(
"-y");
-
//-r 5 fps设置为5帧/秒(不同位置有不同含义) %2d标识图片文件的正则
-
commend.
add(
"-r");
-
commend.
add(
"10");
-
commend.
add(
"d:/out.mp4");
-
start(commend);
-
long endTime =System.currentTimeMillis();
-
System.
out.println((endTime-startTime));
-
}
对比上面,多个图片合成视频的代码,视频加上图片水印,多了如下代码:
commend.add("-i");
commend.add("d:/1557906953.jpg"); //这是图片水印,也就是上图的那个正方形
commend.add("-filter_complex"); //设置滤镜
commend.add((new StringBuilder("[1:v]scale=150:150[s];[0:v][s]overlay=")).append(1800).append(":").append(900)
.toString());
其他的代码,一目了然,很容易懂,可能添加滤镜这段代码很难懂,下面我们把它拆分一下
[1:v]这个里头两个参数,1表示的是操作对象的编号。在本例中0就是图片需要合成视频的有序目录地址,1就是1557906953.png,3就是output.mp4。而另一个参数v表示操作对象里的视频信息。
[1:v]scale=150:150[s];[0:v][s]overlay=1800:900
所以这头一句[1:v]scale=150:150[s];的意思就是对图片1557906953.png进行调节尺寸的操作,并将这个操作的结果命名为s
下一句[0:v][s]overlay=1800:900的意思就是对视频添加水印的的结果s添加水印,overlay就是水印的位置,在数学中,xy正数实在第一象限,而在这里,操作的实际上是第四象限,都为正数。
4.有意思例子
把上面的x坐标1800改为1800-t*30,我们可以看到图片跟着时间再向左运动。
转载自:https://blog.csdn.net/qq_16855077/article/details/90239644