Android ffmpeg 视频剪辑

标签 android ffmpeg

我正在尝试使用 FFmpeg 在我的 Android 应用程序中编辑一些视频,但是当我尝试只拍摄视频的一部分时遇到了一些问题。

我正在使用这个 ffmpeg 编译/lib https://github.com/WritingMinds/ffmpeg-android-java

我尝试使用此命令来修剪/剪切视频

"-y -i input.mp4 -ss 00:00:01.00 -t 00:00:15.000 -c copy output.mp4"

但是对于某些视频,我会出现黑屏或视频卡住。在我的所有测试中,声音都很好。

用这个命令

"-y -i input.mp4 -ss 00:00:01.000 -t 00:00:15.000 -async 1 output.mp4"

在我的所有测试(视频/声音)中一切正常,但生成输出文件需要太多时间,这个 15 秒的文件需要超过 2 分钟才能生成。

我尝试了这些命令的其他变体,但我总是遇到视频流问题(黑屏或卡住)或生成输出花费太多时间(用户只能选择 15 秒的视频发送到我的服务器)

感谢帮助!

编辑:

这是修剪视频的代码部分

String[] cmd = new String[]{"-y","-i",input,"-ss","00:00:05.000","-vcodec","copy",
            "-acodec","copy","-t","00:00:15.00","-strict","-2",output };

    final FFmpeg ffmpeg = FFmpeg.getInstance(this);
    try {
        ffmpeg.execute(cmd, new FFmpegExecuteResponseHandler() {
            @Override
            public void onSuccess(String message) {
                Log.i("VideoEditActivity", "Success " + message);
                is_video_generated_ = true;
            }

            @Override
            public void onProgress(String message) {
                Log.i("VideoEditActivity", "Progress updated " + message);
            }

            @Override
            public void onFailure(String message) {
                Log.e("VideoEditActivity", "ERROR! " + message);
            }

            @Override
            public void onStart() {
                progress_dialog_.setMessage(getString(R.string.str_video_generating));
                progress_dialog_.show();
            }

            @Override
            public void onFinish() {
                Log.i("VideoEditActivity", "Finished");
                progress_dialog_.hide();

                Intent intent = new Intent(getApplicationContext(), VideoPlayActivity.class);
                intent.putExtra("media", edited_video_path_);
                startActivity(intent);
            }
        });
    } catch (FFmpegCommandAlreadyRunningException e) {
        e.printStackTrace();
    }

这是原始文件:[ https://drive.google.com/file/d/0BzqJL_nNetbRYmxvcTljanJwR00/view?usp=sharing][1]

这是输出:0BzqJL_nNetbReENjRGMtVXQ5VHM/view?usp=sharing(堆栈溢出不允许我添加超过 2 个链接)

最佳答案

我遇到过同样的问题,经过大量挖掘,我找到了一个完美的解决方案。

 /**
 * Command for cutting video
 */
private void executeCutVideoCommand(long startMs, long endMs) {

    String destPath = "/storage/emulated/0/DCIM/test/";//Replace ypur dest Path
    File externalStoragePublicDirectory = new File(destPath);
    if (!externalStoragePublicDirectory.exists() ? externalStoragePublicDirectory.mkdir() : true) {
        String yourRealPath = "YOUR INPUT PATH";//getPath(MainActivity.this, selectedVideoUri); 
        String filePrefix = yourRealPath.substring(yourRealPath.lastIndexOf("."));
        String destFileName = "cut_video";
        boolean isFastMode = false;
        File dest = (filePrefix.equals(".webm") || filePrefix.equals(".mkv")) ? new File(externalStoragePublicDirectory, destFileName + ".mp4") : new File(externalStoragePublicDirectory, destFileName + filePrefix);
        int fileNo = 0;
        while (dest.exists()) {
            fileNo++;
            dest = (filePrefix.equals(".webm") || filePrefix.equals(".mkv")) ? new File(externalStoragePublicDirectory, destFileName + fileNo + ".mp4") : new File(externalStoragePublicDirectory, destFileName + fileNo + filePrefix);
        }
        Log.d(TAG, "startTrim: src: " + yourRealPath);
        Log.d(TAG, "startTrim: dest: " + dest.getAbsolutePath());
        Log.d(TAG, "startTrim: startMs: " + startMs);
        Log.d(TAG, "startTrim: endMs: " + endMs);
        filePath = dest.getAbsolutePath();
        final String[] complexCommand = isFastMode ?
                (filePrefix.equals(".webm") || filePrefix.equals(".mkv") || filePrefix.equals(".m4v") || filePrefix.equals(".mov")) ?
                        new String[]{"-ss", "" + (startMs / 1000), "-y", "-i", yourRealPath, "-preset", "ultrafast", "-t", "" + ((endMs - startMs) / 1000), "-vcodec", "mpeg4", "-b:v", "2097152", "-b:a", "48000", "-ac", "2", "-ar", "22050", "-strict", "-2", filePath}
                        : new String[]{"-y", "-i", yourRealPath, "-preset", "ultrafast", "-ss", "" + (startMs / 1000), "-t", "" + ((endMs - startMs) / 1000), "-c", "copy", filePath}
                : (filePrefix.equals(".webm") || filePrefix.equals(".mkv") || filePrefix.equals(".m4v") || filePrefix.equals(".mov")) ?
                new String[]{"-ss", "" + (startMs / 1000), "-y", "-i", yourRealPath, "-t", "" + ((endMs - startMs) / 1000), "-vcodec", "mpeg4", "-b:v", "2097152", "-b:a", "48000", "-ac", "2", "-ar", "22050", "-strict", "-2", filePath} :
                new String[]{"-y", "-i", yourRealPath, "-ss", "" + (startMs / 1000), "-t", "" + ((endMs - startMs) / 1000), "-c", "copy", filePath};
        execFFmpegBinary(complexCommand);
    }
}

execFFmpegBinary(complexCommand)

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

            }

            @Override
            public void onProgress(String s) {
                Log.d(TAG, "Started command : ffmpeg " + command);

            }

            @Override
            public void onStart() {
                Log.d(TAG, "Started command : ffmpeg " + command);

            }

            @Override
            public void onFinish() {
                Log.d(TAG, "Finished command : ffmpeg " + command);


            }
        });
    } catch (FFmpegCommandAlreadyRunningException e) {
        // do nothing for now
    }
}

关于Android ffmpeg 视频剪辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40121065/

相关文章:

audio - 如何以编程方式调整音频文件的文件夹,使它们的响度大致相同?

python - x264 多次通过指定临时文件的位置?

java - 如何使用反射实现回调?

android - 运行将接收 SCREEN_ON 广播的服务

Android,将文件写入数据/数据/'package'文件夹的子目录的正确方法是什么

ffmpeg - 如何从 m4a 文件中删除 tx3g 流

ffmpeg 手动生成 m3u8 和分段

audio - 如何使用 ffmpeg 将 6 个音频 channel 转换为一个 5.1 channel ?

Android:具有变速 API 23 的视频

android - 如何使用 URL 处理多个微调器?