【问题标题】:FFmpeg: complex command for extracting imageFFmpeg:用于提取图像的复杂命令
【发布时间】:2017-07-20 17:53:52
【问题描述】:

我在 android studio 2.3.3 上的 ANDROID APPLICATION 的 ffmpeg 使用以下代码编译:

编译'com.writingminds:FFmpegAndroid:0.3.2'

在下面的代码中我有这行代码:

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

我想知道的:

  1. 如何更改我拥有的复杂命令,以便获得 2 秒长 30fps 视频的最后 15 帧。

这是我引用的代码:

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

代码下载自:

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

【问题讨论】:

    标签: android video ffmpeg


    【解决方案1】:

    使用select 过滤器按索引选择特定帧。

    2 秒 30 fps 的视频有 60 帧,因此您需要从 45 开始的所有帧:

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

    还有其他选择表达式,例如 ltebetween,请参阅 ffmpeg 文档中的 Expression Evaluation-vsync 0 丢弃帧时间戳以消除重复。

    最终的命令如下所示:

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

    【讨论】:

    • 嘿@slhck 我如何将你的代码实现到我的?像这样简单地改变 ComplexCommand: String[] complexCommand = {ffmpeg, "-i" ,"input.mp4", "-vf", "select=gte(n\,45)", "out-%04d.png "};似乎不起作用。
    • 你能弄明白吗?通过 Java 调用它时,您可能不必使用反斜杠,因此请尝试 select=gte(n,45)。如果它不起作用,请显示一些错误输出。
    • 我收到这些错误:我不能使用 '\' 它在构建过程中给出错误“非法转义字符”。使用斜线:[AVFilterGraph @ 0xf689a080] 使用参数 'gte(n/'
    • String[] complexCommand = {"-y", "-i", yourRealPath, "-an", "-r", "60", "-ss", "" + startMs / 1000, "-t", "" + (endMs - startMs) / 1000, dest.getAbsolutePath()};上面的 complexCommand 允许我从 60fps 1 秒的视频中抓取所有 60 帧,但我需要的是最后“x”帧数量 Idk 如何更改复杂命令以满足我的需要
    • 我无法在我的系统上尝试,但也许您可以尝试:"select='gte(n,45)'"(带单引号)。
    猜你喜欢
    • 1970-01-01
    • 2020-04-26
    • 2021-01-01
    • 1970-01-01
    • 2011-06-21
    • 1970-01-01
    • 2019-05-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多