bravobit / FFmpeg-Android

FFMpeg/FFprobe compiled for Android
https://bravobit.nl/
MIT License
734 stars 172 forks source link

[Solved] how to use two-pass encoding #129

Open symphonyrecords opened 4 years ago

symphonyrecords commented 4 years ago

There are two notes when you want to use two-pass encoding.

Note 1 : use "-f null -" for null pipeline

Note 2 : override -passlogfile: like: -passlogfile /mnt/sdcard/logFilePrefix

ffmpeg by default will write passlogfile in an inaccessible path in android, so if you don't override it, encoding process will fail immediately complaining:

Cannot write log file 'ffmpeg2pass-0.log' for pass-1/pass-2 encoding: Read-only file system


full example of a Two-pass encoding in Android

public static void run2PassEncoding(Context context) {

    String tempLogPath = "/storage/emulated/0/2passLog";
    String inputPath = "/storage/emulated/0/myVideo.mp4";
    String output = "/storage/emulated/0/output.mp4";

    List<String> pass1Commands = new LinkedList<>();
    pass1Commands.add("-y");
    pass1Commands.add("-i");
    pass1Commands.add(inputPath);
    pass1Commands.add("-codec:v");
    pass1Commands.add("libx264");
    pass1Commands.add("-passlogfile");
    pass1Commands.add(tempLogPath);
    pass1Commands.add("-preset");
    pass1Commands.add("veryfast");
    pass1Commands.add("-b:v");
    pass1Commands.add("500k");
    pass1Commands.add("-maxrate");
    pass1Commands.add("500k");
    pass1Commands.add("-bufsize");
    pass1Commands.add("1000k");
    pass1Commands.add("-vf");
    pass1Commands.add("scale=420:-2");
    pass1Commands.add("-pass");
    pass1Commands.add("1");
    pass1Commands.add("-an");
    pass1Commands.add("-f");
    pass1Commands.add("null");
    pass1Commands.add("-");

    List<String> pass2Commands = new LinkedList<>();
    pass2Commands.add("-y");
    pass2Commands.add("-i");
    pass2Commands.add(inputPath);
    pass2Commands.add("-codec:v");
    pass2Commands.add("libx264");
    pass2Commands.add("-passlogfile");
    pass2Commands.add(tempLogPath);
    pass2Commands.add("-preset");
    pass2Commands.add("fast");
    pass2Commands.add("-b:v");
    pass2Commands.add("500k");
    pass2Commands.add("-maxrate");
    pass2Commands.add("500k");
    pass2Commands.add("-bufsize");
    pass2Commands.add("1000k");
    pass2Commands.add("-vf");
    pass2Commands.add("scale=420:-2");
    pass2Commands.add("-pass");
    pass2Commands.add("2");
    pass2Commands.add("-codec:a");
    pass2Commands.add("libfdk_aac");
    pass2Commands.add("-b:a");
    pass2Commands.add("128k");
    pass2Commands.add(output);

    FFmpeg.getInstance(context).execute(pass1Commands.toArray(new String[0]),  new ExecuteBinaryResponseHandler() {
        @Override
        public void onSuccess(String message) {
            super.onSuccess(message);
            Log.i("FFMPEG_PASS1: " + "onSuccess" , message);

            FFmpeg.getInstance(context).execute(pass2Commands.toArray(new String[0]), new ExecuteBinaryResponseHandler() {
                @Override
                public void onSuccess(String message) {
                    super.onSuccess(message);
                    Log.i("FFMPEG_PASS2: " + "onSuccess" , message);
                }
                @Override
                public void onFailure(String message) {
                    super.onFailure(message);
                    Log.i("FFMPEG_PASS2:" + "onFailure" , message);
                }
            });
        }

        @Override
        public void onFailure(String message) {
            super.onFailure(message);
            Log.i("FFMPEG_PASS1:" + "onFailure" , message);
        }
    });

}