Search code examples
androidvideoandroid-ndkffmpegjava-native-interface

Android - concatenate two videos


I'm trying to concatenate two videos on Android. I'm already using ffmpeg for other needs, but I'm using halfninja's one, which is only 0.9. The 0.9 one doesn't allow the following ways to do it:

// 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
});

The third thing I tried is to use the concat demuxer explained here, which isn't recognized with ffmpeg 0.9 either.

Is there any way to concatenate two videos on Android with ffmpeg 0.9 (or another library)?


Solution

  • Well, the only solution found was to use ffmpeg ≥1.1. I compiled the 2.1, it's working just fine. Here's what I use now:

    /**
     * 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();
    }