做短视频拍摄时,在分段录制结束需要将多个视频片段拼接成一个视频文件,然后进入预览界面播放。
有两种方案:
方案一:使用 FFMpeg 进行视频拼接,命令如下:
// inputListFilePath 为需要合并的文件列表文件,每行一个文件路径
String cmd = "ffmpeg -y -f concat -safe 0 -i " + inputListFilePath + " -c copy " + outputFilePath;
方案二:使用开源库 mp4parser 做多视频片段拼接
本文主要介绍方案二。
使用时先在 gradle 中配置依赖:
compile 'com.googlecode.mp4parser:isoparser:1.1.21'
将 mp4parser 封装成音视频合并工具类,合并函数如下:
package com.alanwang.aav.alvideoeditor.core;
import com.coremedia.iso.boxes.Container;
import com.googlecode.mp4parser.authoring.Movie;
import com.googlecode.mp4parser.authoring.Track;
import com.googlecode.mp4parser.authoring.builder.DefaultMp4Builder;
import com.googlecode.mp4parser.authoring.container.mp4.MovieCreator;
import com.googlecode.mp4parser.authoring.tracks.AppendTrack;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* Author: AlanWang4523.
* Date: 19/4/15 01:46.
* Mail: alanwang4523@gmail.com
*/
public class AWMp4ParserHelper {
private final static String PREFIX_VIDEO_HANDLER = "vide";
private final static String PREFIX_AUDIO_HANDLER = "soun";
/**
* 合并视频
* @param inputVideos
* @param outputPath
* @throws IOException
*/
public static void mergeVideos(List<String> inputVideos, String outputPath) throws IOException {
List<Movie> inputMovies = new ArrayList<>();
for (String input : inputVideos) {
inputMovies.add(MovieCreator.build(input));
}
List<Track> videoTracks = new LinkedList<>();
List<Track> audioTracks = new LinkedList<>();
for (Movie m : inputMovies) {
for (Track t : m.getTracks()) {
if (PREFIX_AUDIO_HANDLER.equals(t.getHandler())) {
audioTracks.add(t);
}
if (PREFIX_VIDEO_HANDLER.equals(t.getHandler())) {
videoTracks.add(t);
}
}
}
Movie outputMovie = new Movie();
if (audioTracks.size() > 0) {
outputMovie.addTrack(new AppendTrack(audioTracks.toArray(new Track[audioTracks.size()])));
}
if (videoTracks.size() > 0) {
outputMovie.addTrack(new AppendTrack(videoTracks.toArray(new Track[videoTracks.size()])));
}
Container out = new DefaultMp4Builder().build(outputMovie);
FileChannel fc = new RandomAccessFile(outputPath, "rw").getChannel();
out.writeContainer(fc);
fc.close();
}
}
使用 Mp4Parser 进行视频裁剪请见我的另外一篇博客 《 Android 使用 mp4parser 做视频裁剪》;