【问题标题】:How to trim the video with start & end time in android programmatically?如何以编程方式在android中修剪带有开始和结束时间的视频?
【发布时间】:2018-11-03 04:35:58
【问题描述】:

我想以编程方式在 android 中根据开始和结束时间修剪本地视频,我尝试在下面附加几个链接但对我没有用。请让我知道任何工作库或示例代码来克服这个问题?

参考链接:

  1. Android sdk cut/trim video file
  2. How to trim the video using FFMPEG library in android?
  3. https://superuser.com/questions/377343/cut-part-from-video-file-from-start-position-to-end-position-with-ffmpeg

提前致谢!

【问题讨论】:

    标签: android video android-library video-editing


    【解决方案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);"即使集成上述库也显示错误?
    • 无法创建“execFFmpegBinary(complexCommand);”下面“Sam Raju”的回答帮助我创造了这个。
    • 执行 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
    • 请检查您设置的所有条件,例如存储的读取、写入和访问权限以及所有可能因为您收到此错误的条件。
    • 我也已授予所有权限...但错误仍然存​​在@mahes Keshavala
    【解决方案2】:

    使用 FFMPEG 库来解决您的问题。感谢您为 android 简化 ffmpeg 的写作思路 1.implementation 'com.writingminds:FFmpegAndroid:0.3.2'

    1. 初始化 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. 使用FFMPEG command 就像上面发布的@Mahesh Keshvala。干得好@Mahesh

    3. 那么execFFmpegBinary(complexCommand);会是这样的

      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
       }
      }
      

    尝试剪切视频的命令

    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 android 的信息请参考this link

    【讨论】:

    • 执行 execFFmpegBinary 块时显示以下错误。错误:E/FFmpeg:尝试运行时出现异常:[Ljava.lang.String;@dbe0367 java.io.IOException:运行 exec() 时出错。命令:[/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]工作目录:null 环境:null
    • 05-24 11:10:52.474 19740-19740/com.psp.testvideotrim E/事件:onFailure - 05-24 11:10:52.475 19740-19740/com.psp.testvideotrim E/事件:onFinish
    • 我更新了我的答案,请检查,也请参考link。我在我的一个项目中使用了相同的方法
    • 这不适用于android 10。你可以使用这个库github.com/a914-gowtham/Android-video-trimmer
    • @gowtham6672 链接已损坏,我认为图书馆不再维护。
    【解决方案3】:

    更新了 Kotlin 中的解决方案 ffmpeg 库。此解决方案已使用 SDK 版本 21 至 30 进行测试。

    首先需要添加依赖

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

    下面是剪辑视频的代码sn-p。

    注意:您需要使用 AsyncTask 或 Kotlin Coroutines 在后台线程中运行以下代码

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

    【讨论】:

      猜你喜欢
      • 2020-09-21
      • 2021-07-26
      • 2023-02-20
      • 1970-01-01
      • 2013-08-28
      • 2015-09-11
      • 2013-12-16
      • 2021-07-18
      • 1970-01-01
      相关资源
      最近更新 更多