在Android中如何以编程方式按开始和结束时间剪辑视频?

6
3个回答

5
使用FFMPEG库解决您的问题。感谢writingminds让ffmpeg在安卓上变得简单。
1. `implementation 'com.writingminds:FFmpegAndroid:0.3.2'`
  1. initialize ffmpeg

    private void setUpFFmpeg() {
    ffmpeg = FFmpeg.getInstance(context);
    
    
    try {
        ffmpeg.loadBinary(new LoadBinaryResponseHandler() {
    
            @Override
            public void onStart() {
                Log.d("Event ", "onStart");
            }
    
            @Override
            public void onFailure() {
                Log.d("Event ", "onFailure");
            }
    
            @Override
            public void onSuccess() {
                Log.d("Event ", "onSuccess");
            }
    
            @Override
            public void onFinish() {
                Log.d("Event ", "onFinish");
    
            }
        });
    } catch (FFmpegNotSupportedException e) {
        // Handle if FFmpeg is not supported by device
    }
    }
    
  2. use FFMPEG command like @Mahesh Keshvala posted above. Good work @Mahesh

  3. then execFFmpegBinary(complexCommand); will be like this

    private void execFFmpegBinary(String[] command){
          try {
    
        ffmpeg.execute(commands, new ExecuteBinaryResponseHandler() {
    
            @Override
            public void onStart() {
                Log.d("Event ", "onStart");
            }
    
            @Override
            public void onProgress(String message) {
                Log.e("Event ", "onProgress - " + message);
    
            }
    
            @Override
            public void onFailure(String message) {
                Log.e("Event ", "onFailure - " + message);
    
            }
    
            @Override
            public void onSuccess(String message) {
                Log.e("Event ", "onSuccess - " + message);
    
            }
    
            @Override
            public void onFinish() {
                Log.e("Event ", "onFinish");
    
            }
        });
    } catch (FFmpegCommandAlreadyRunningException e) {
        // Handle if FFmpeg is already running
     }
    }
    

剪辑视频的try命令

String[] complexCommand = {"-ss", "" + startMs / 1000, "-y", "-i", inputFileAbsolutePath, "-t", "" + (endMs - startMs) / 1000, "-s", "320x240", "-r", "15", "-vcodec", "mpeg4", "-b:v", "2097152", "-b:a", "48000", "-ac", "2", "-ar", "22050", outputFileAbsolutePath};

要了解更多关于ffmpeg在安卓设备上的使用,请参考这个链接


在执行execFFmpegBinary块时出现以下错误。错误:E/FFmpeg: Exception while trying to run: [Ljava.lang.String;@dbe0367 java.io.IOException: Error running exec(). Command: [/data/user/0/com.psp.testvideotrim/files/ffmpeg, -ss, 0, -y, -i, /storage/emulated/0/test/Media/test Video/VID-20180522-WA0008.mp4, -t, 3, -vcodec, mpeg4, -b:v, 2097152, -b:a, 48000, -ac, 2, -ar, 22050, /storage/emulated/0/Movies/cut_video.mp4] Working Directory: null Environment: null - Srinivasa Prudhvi Pendem
05-24 11:10:52.474 19740-19740/com.psp.testvideotrim E/Event: 失败 - 05-24 11:10:52.475 19740-19740/com.psp.testvideotrim E/Event: 完成 - Srinivasa Prudhvi Pendem
我更新了我的答案,请检查一下,并参考这个链接:https://androidlearnersite.wordpress.com/2017/03/17/ffmpeg-video-editor/。我在一个项目中使用了相同的方法。 - Sam Raju
这在Android 10上不起作用。您可以使用此库 https://github.com/a914-gowtham/Android-video-trimmer - gowtham6672
这个答案不适用于SDK级别大于9的情况。您可以在下面检查我的更新答案。https://dev59.com/Uqvka4cB1Zd3GeqPwKBS#65741422 - Hantash Nadeem
显示剩余2条评论

1

以下是使用FFMPEG库的解决方案,使用下面的函数来裁剪或剪辑视频,也许这对你有用:

private void executeCutVideoCommand(int startMs, int endMs) {
    File moviesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES
    );

    String filePrefix = "cut_video";
    String fileExtn = ".mp4";
    String yourRealPath = getPath(VideoEffectActivity.this, selectedVideoUri);
    File dest = new File(moviesDir, filePrefix + fileExtn);
    int fileNo = 0;
    while (dest.exists()) {
        fileNo++;
        dest = new File(moviesDir, filePrefix + fileNo + fileExtn);
    }

    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();
    //String[] complexCommand = {"-i", yourRealPath, "-ss", "" + startMs / 1000, "-t", "" + endMs / 1000, dest.getAbsolutePath()};
    String[] complexCommand = {"-ss", "" + startMs / 1000, "-y", "-i", yourRealPath, "-t", "" + (endMs - startMs) / 1000, "-vcodec", "mpeg4", "-b:v", "2097152", "-b:a", "48000", "-ac", "2", "-ar", "22050", filePath};

    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);
               //You have to create a class of Preview Activity
               //If you don't have please remove below Intent code
                    Intent intent = new Intent(VideoEffectActivity.this, PreviewActivity.class);
                    intent.putExtra(FILEPATH, filePath);
                    startActivity(intent);
            }

            @Override
            public void onProgress(String s) {
                    progressDialog.setMessage("progress : " + s);
                Log.d(TAG, "progress : " + s);
            }

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

            @Override
            public void onFinish() {
                Log.d(TAG, "Finished command : ffmpeg " + command);
               progressDialog.dismiss();
            }
        });
    } catch (FFmpegCommandAlreadyRunningException e) {
        // do nothing for now
    }
}

将此依赖项放入gradle文件中:

    compile 'com.writingminds:FFmpegAndroid:0.3.2'

即使集成了上述库,执行“execFFmpegBinary(complexCommand)”仍然出现错误? - Srinivasa Prudhvi Pendem
无法创建 "execFFmpegBinary(complexCommand);"。以下"Sam Raju"的答案帮助我创建了它。 - Srinivasa Prudhvi Pendem
执行execFFmpegBinary块时出现以下错误。错误: E/FFmpeg: 尝试运行时出现异常:[Ljava.lang.String;@a1d6f03 java.io.IOException: 运行exec()时出错。 命令:[/data/user/0/com.psp.testvideotrim/files/ffmpeg,-i,/storage/emulated/0/WhatsApp Business/Media/WhatsApp Business Video/VID-20180522-WA0000.mp4,-ss,0,-t,30,/storage/emulated/0/Movies/cut_video.mp4] 工作目录:null 环境:null - Srinivasa Prudhvi Pendem
请检查您设置的所有条件,例如读取、写入和访问存储权限等,可能是因为这些原因导致了此错误。 - Mahesh Keshvala
我已经授予了所有权限...但错误仍然存在@mahes Keshavala - Srinivasa Prudhvi Pendem
请使用此库 https://github.com/a914-gowtham/Android-video-trimmer - gowtham6672

0

在 Kotlin 中更新了与 SDK 版本21到30经过测试的 FFmpeg库 的解决方案。

首先,您需要添加依赖项。

implementation 'com.arthenica:mobile-ffmpeg-full:4.2.2.LTS'

以下是剪辑视频的代码片段。
注:您需要使用AsyncTask或Kotlin协程在后台线程中运行下面的代码。
val outputFile = UtilsFile.createVideoFile(context)
        val command =
            arrayOf(
                "-ss",
                "1",    //Start point in seconds
                "-y",
                "-i",
                inputFile.absolutePath,
                "-t",
                "60",   //Ending point in seconds
                "-s",
                "648x1152",
                "-r",
                "15",
                "-vcodec",
                "mpeg4",
                "-b:v",
                "2097152",
                "-b:a",
                "48000",
                "-ac",
                "2",
                "-ar",
                "22050",
                outputFile.absolutePath
            )
        val rc = FFmpeg.execute(command)

        if (rc == RETURN_CODE_SUCCESS) {
            Log.i(TAG, "Command execution completed successfully.")
            return outputFile
        } else if (rc == RETURN_CODE_CANCEL) {
            Log.i(TAG, "Command execution cancelled by user.")
        } else {
            Log.i(
                TAG,
                String.format(
                    "Command execution failed with rc=%d and the output below.",
                    rc
                )
            )
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接