我试图在Android上连接两个视频。我已经在使用ffmpeg满足其他需求了,但我使用halfninja's one,只有0.9。 0.9之所以不允许以下方式:
// filter_complex isn't recognized
vk.run(new String[] {
"ffmpeg",
"-i",
inputFile1,
"-i",
inputFile2,
"-filter_complex",
"'[0:1] [0:0] [1:1] [1:0] concat=n=2:v=1:a=1 [v] [a]'",
"-map",
"'[v]'",
"-map",
"'[a]'",
outputFile
});
// Or, after converting the two videos to ts, trying to merge them: concat:file1.ts|file2.ts: No such file or directory
vk.run(new String[] {
"ffmpeg",
"-i",
"'concat:" + ts1 + "|" + ts2 + "'",
"-vcodec",
"copy",
"-acodec",
"copy",
"-absf",
"aac_adtstoasc",
output
});
我尝试的第三件事是使用解释here的concat demuxer,它也不被ffmpeg 0.9识别。
有没有办法在Android上用ffmpeg 0.9(或其他库)连接两个视频?
答案 0 :(得分:7)
嗯,找到的唯一解决方案是使用ffmpeg≥1.1。我编译了2.1,它工作得很好。这是我现在使用的:
/**
* Concatenates two videos
* @param inputFile1 First video file path
* @param inputFile2 Second video file path
* @param outputFile Output file path
*/
public static void concatenate(String inputFile1, String inputFile2, String outputFile) {
Log.d(TAG, "Concatenating " + inputFile1 + " and " + inputFile2 + " to " + outputFile);
String list = generateList(new String[] {inputFile1, inputFile2});
Videokit vk = Videokit.getInstance();
vk.run(new String[] {
"ffmpeg",
"-f",
"concat",
"-i",
list,
"-c",
"copy",
outputFile
});
}
/**
* Generate an ffmpeg file list
* @param inputs Input files for ffmpeg
* @return File path
*/
private static String generateList(String[] inputs) {
File list;
Writer writer = null;
try {
list = File.createTempFile("ffmpeg-list", ".txt");
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(list)));
for (String input: inputs) {
writer.write("file '" + input + "'\n");
Log.d(TAG, "Writing to list file: file '" + input + "'");
}
} catch (IOException e) {
e.printStackTrace();
return "/";
} finally {
try {
if (writer != null)
writer.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
Log.d(TAG, "Wrote list file to " + list.getAbsolutePath());
return list.getAbsolutePath();
}
答案 1 :(得分:1)
如果您的视频具有相同的编码,Marc的答案将会有效。我正在使用它来合并我的应用程序中录制的视频。当您从前置摄像头和后置摄像头录制视频时,它会混合音频(这可能是因为视频之间的帧速率不同)。所以我使用了以下命令,但它比使用列表合并慢得多,因为它不检查编码。
final FFmpeg ffmpeg = FFmpeg.getInstance(activity);
List<String> cmdList = new ArrayList<>();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < videoFilenameList.size(); i++)
{
cmdList.add("-i");
cmdList.add(videoFilenameList.get(i));
sb.append("[").append(i).append(":0] [").append(i).append(":1]");
}
sb.append(" concat=n=").append(videoFilenameList.size()).append(":v=1:a=1 [v] [a]");
cmdList.add("-filter_complex");
cmdList.add(sb.toString());
cmdList.add("-map");
cmdList.add("[v]");
cmdList.add("-map");
cmdList.add("[a]");
cmdList.add("-preset");
cmdList.add("ultrafast");
cmdList.add(outFile);
sb = new StringBuilder();
for (String str : cmdList)
{
sb.append(str).append(" ");
}
String[] cmd = cmdList.toArray(new String[cmdList.size()]);
ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler()
{
@Override
public void onSuccess(String message)
{
}
@Override
public void onFailure(String message)
{
}
@Override
public void onProgress(String message)
{
}
@Override
public void onStart()
{
}
@Override
public void onFinish()
{
}
}