Tix
Tix

Reputation: 449

FFmpeg: complex command for extracting image

My ffmpeg for my ANDROID APPLICATION on android studio 2.3.3 is compiled using this:

compile 'com.writingminds:FFmpegAndroid:0.3.2'

In the code below i have this line of code:

String[] complexCommand = {"-i", yourRealPath, "-c:v", "libx264", "-crf", "22", "-map", "0", "-segment_time", "6", "-g", "9", "-sc_threshold", "0", "-force_key_frames", "expr:gte(t,n_forced*6)", "-f", "segment", dest.getAbsolutePath()};

What i want to know:

  1. How do i change that complex command that i have such that i can get the last 15 frames of a 2 seconds-long 30fps video.

This is the code I'm referencing:

     /**
     * Command for extracting images from video
     */
    private void extractImagesVideo(int startMs, int endMs) {
        File moviesDir = Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES
        );

        String filePrefix = "extract_picture";
        String fileExtn = ".jpg";
        String yourRealPath = getPath(MainActivity.this, selectedVideoUri);

        File dir = new File(moviesDir, "VideoEditor");
        int fileNo = 0;
        while (dir.exists()) {
            fileNo++;
            dir = new File(moviesDir, "VideoEditor" + fileNo);

        }
        dir.mkdir();
        filePath = dir.getAbsolutePath();
        File dest = new File(dir, filePrefix + "%03d" + fileExtn);


        Log.d(TAG, "startTrim: src: " + yourRealPath);
        Log.d(TAG, "startTrim: dest: " + dest.getAbsolutePath());

        String[] complexCommand = {"-y", "-i", yourRealPath, "-an", "-r", "1/2", "-ss", "" + startMs / 1000, "-t", "" + (endMs - startMs) / 1000, dest.getAbsolutePath()};

        execFFmpegBinary(complexCommand);

    }

 /**
     * Executing ffmpeg binary
     */
    private void execFFmpegBinary(final String[] command) {
        try {
            ffmpeg.execute(command, new ExecuteBinaryResponseHandler() {
                @Override
                public void onFailure(String s) {
                    Log.d(TAG, "FAILED with output : " + s);
                }

                @Override
                public void onSuccess(String s) {
                    Log.d(TAG, "SUCCESS with output : " + s);
                    if (choice == 1 || choice == 2 || choice == 5 || choice == 6 || choice == 7) {
                        Intent intent = new Intent(MainActivity.this, PreviewActivity.class);
                        intent.putExtra(FILEPATH, filePath);
                        startActivity(intent);
                    } else if (choice == 3) {
                        Intent intent = new Intent(MainActivity.this, PreviewImageActivity.class);
                        intent.putExtra(FILEPATH, filePath);
                        startActivity(intent);
                    } else if (choice == 4) {
                        Intent intent = new Intent(MainActivity.this, AudioPreviewActivity.class);
                        intent.putExtra(FILEPATH, filePath);
                        startActivity(intent);
                    } else if (choice == 8) {
                        choice = 9;
                        reverseVideoCommand();
                    } else if (Arrays.equals(command, lastReverseCommand)) {
                        choice = 10;
                        concatVideoCommand();
                    } else if (choice == 10) {
                        File moviesDir = Environment.getExternalStoragePublicDirectory(
                                Environment.DIRECTORY_MOVIES
                        );
                        File destDir = new File(moviesDir, ".VideoPartsReverse");
                        File dir = new File(moviesDir, ".VideoSplit");
                        if (dir.exists())
                            deleteDir(dir);
                        if (destDir.exists())
                            deleteDir(destDir);
                        choice = 11;
                        Intent intent = new Intent(MainActivity.this, PreviewActivity.class);
                        intent.putExtra(FILEPATH, filePath);
                        startActivity(intent);
                    }
                }

Code downloaded from:

https://github.com/bhuvnesh123/FFmpeg-Video-Editor-Android

Upvotes: 0

Views: 580

Answers (1)

slhck
slhck

Reputation: 38672

Use the select filter to select specific frames by their index.

2 seconds of video at 30 fps have 60 frames, so you want all frames from 45 onwards:

ffmpeg -i input.mp4 -vf "select='gte(n,45)'" -vsync 0 out-%04d.png

There are other selection expressions like lte or between, see Expression Evaluation in the ffmpeg docs. -vsync 0 drops frame timestamps to eliminate duplicates.

The final command would look like this:

String[] complexCommand = {"-y", "-i", yourRealPath, "-an", "-framerate", "60", "-vf", "select='gte(n,45)'", "-vsync", "0", dest.getAbsolutePath()};

Upvotes: 2

Related Questions