主要用ffmpeg,将视频拆分成一帧帧图片,然后分别修改图片,再重新合成视频
断断续续搞了几个月,先记录一下。
public static void makeVideos(String videoPath,List<List<String>> txs, String srcmusic,String targetPath){
String tem="c:/temspace/"+FileUtil.getFileNameWithoutSuffix(videoPath);
//生成每一帧
FfmpegUtil.video2Images(videoPath, tem);
List<String> imgs = FileUtil.orderNameByNumber(FileUtil.getAllSubPath(tem));
//修改帧数
Map<String, Object> info = FfmpegUtil.getVideoInfo(videoPath);
int totalframe=Integer.parseInt(info.get("totalframe").toString());
int fps=Integer.parseInt(info.get("fps").toString());
int newfps=fps-1;
List<String> newimgs=new ArrayList<String>();
for (int i = 0; i < (totalframe/fps); i++) {
Map<Integer, Integer> position = VideoImageUtil.setPosition(newfps, fps);
for(int key:MapUtil.orderMapKey(position)){
int v=position.get(key);
newimgs.add(imgs.get(i*fps+v-1));
}
}
for (int i = (totalframe/fps)*fps; i < totalframe; i++) {
newimgs.add(imgs.get(i));
}
imgs.removeAll(newimgs);
FileUtil.delFile(imgs);
FileUtil.rename_ordernum(newimgs,1);
imgs = FileUtil.orderNameByNumber(FileUtil.getAllSubPath(tem));
//每一帧加上特效
List<Integer> idxs=new ArrayList<>();
for (int i = 0; i < txs.size(); i++) {
idxs.add(1);
}
for (int i = 0; i < imgs.size(); i++) {
for (int j = 0; j < idxs.size(); j++) {
if(idxs.get(j)>=txs.get(j).size()) idxs.set(j, 0);
}
for (int j = 0; j < txs.size(); j++) {
List<String> tx = txs.get(j);
ImageBorderUtil.screen(imgs.get(i), tx.get(idxs.get(j)), imgs.get(i));
idxs.set(j, idxs.get(j)+1);
}
ImageUtil.gaussian(imgs.get(i), 0, 990, 576, 34, 20, imgs.get(i));
ImageUtil.gaussian_gradual(imgs.get(i), 0, 0, 576, 30, false,20, imgs.get(i));
}
//生成视频
String temvideo="c:/temspace/"+System.currentTimeMillis()+".mp4";
String usemusic="c:/temspace/"+System.currentTimeMillis()+".wav";
boolean issrcmusic=false;
FfmpegUtil.images2Video(tem, newfps,temvideo);
Map<String, Object> teminfo = FfmpegUtil.getVideoInfo(temvideo);
long len=1000*Long.parseLong(teminfo.get("milstimelen").toString());//视频长度 微秒
long microsecond = WavUtil.getMicrosecond(srcmusic);//音乐长度 微秒
if(len>microsecond){//音乐太短,重复补足到视频长度
int time=(int) (len/microsecond);
List<String> subfiles=new ArrayList<String>();
for (int i = 0; i < time; i++) {
subfiles.add(srcmusic);
}
long cutlen=len%microsecond;
String temleftaudio="";
if(cutlen>0){
temleftaudio="c:/temspace/"+System.currentTimeMillis()+".wav";
WavUtil.cut(srcmusic, temleftaudio, 0, cutlen);
subfiles.add(temleftaudio);
}
WavUtil.mergeAudio(subfiles,usemusic);
if(!"".equals(temleftaudio)) FileUtil.del(temleftaudio);
}else if(len<microsecond){//音乐太长,截取
WavUtil.cut(srcmusic, usemusic, 0, len);
}else{
usemusic=srcmusic;
issrcmusic=true;
}
FfmpegUtil.combineVideoAndAudio(temvideo, usemusic, targetPath);
FileUtil.del(temvideo);
if(!issrcmusic) FileUtil.del(usemusic);
FileUtil.del(tem);
}