在 Android 中使用 FFmpeg 将视频裁剪为方形格式

Posted

技术标签:

【中文标题】在 Android 中使用 FFmpeg 将视频裁剪为方形格式【英文标题】:Use FFmpeg to crop a video to square format in Android 【发布时间】:2016-08-15 20:43:23 【问题描述】:

我目前正在开发一款应该将 16:9 视频裁剪为 1:1 视频的应用。但是我没有让代码工作。如果可能,软件应尽快转换输入的视频。分辨率可以在 480x480 和 720x720 之间变化。

如果我可以选择裁剪框的位置就完美了。

我得到的错误:

E/FFmpeg: Exception while trying to run: [Ljava.lang.String;@f0c91b8
java.io.IOException: Error running exec(). Command: [/data/user/0/com.android.grafika/files/ffmpeg, -i /storage/emulated/0/Alphacrypt1.mp4 -vf crop=640:256:0:400 -threads 5 -preset ultrafast -strict -2 /storage/emulated/0/YourCroppedMovie.mp4] Working Directory: null Environment: null
at java.lang.ProcessManager.exec(ProcessManager.java:215)
at java.lang.Runtime.exec(Runtime.java:174)
at java.lang.Runtime.exec(Runtime.java:129)
at com.github.hiteshsondhi88.libffmpeg.ShellCommand.run(ShellCommand.java:10)
at com.github.hiteshsondhi88.libffmpeg.FFmpegExecuteAsyncTask.doInBackground(FFmpegExecuteAsyncTask.java:38)
at com.github.hiteshsondhi88.libffmpeg.FFmpegExecuteAsyncTask.doInBackground(FFmpegExecuteAsyncTask.java:10)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.io.IOException: No such file or directory
at java.lang.ProcessManager.exec(Native Method)
at java.lang.ProcessManager.exec(ProcessManager.java:213)
at java.lang.Runtime.exec(Runtime.java:174) 
at java.lang.Runtime.exec(Runtime.java:129) 
at com.github.hiteshsondhi88.libffmpeg.ShellCommand.run(ShellCommand.java:10) 
at com.github.hiteshsondhi88.libffmpeg.FFmpegExecuteAsyncTask.doInBackground(FFmpegExecuteAsyncTask.java:38) 
at com.github.hiteshsondhi88.libffmpeg.FFmpegExecuteAsyncTask.doInBackground(FFmpegExecuteAsyncTask.java:10) 
at android.os.AsyncTask$2.call(AsyncTask.java:295) 
at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
at java.lang.Thread.run(Thread.java:818) 

我正在使用的代码:

final String[] cmd = new String[]"-i /storage/emulated/0/Alphacrypt1.mp4 -vf crop=640:256:0:400 -threads 5 -preset ultrafast -strict -2 /storage/emulated/0/YourCroppedMovie.mp4";

    try 
        final FFmpeg ffmpeg = FFmpeg.getInstance(this);
        ffmpeg.execute(cmd, new FFmpegExecuteResponseHandler() 
            @Override
            public void onSuccess(String message) 
                Toast.makeText(getApplicationContext(), "Successfully converted!",
                        Toast.LENGTH_LONG).show();
            

            @Override
            public void onProgress(String message) 

            

            @Override
            public void onFailure(String message) 
                Toast.makeText(getApplicationContext(), "Fail!"+ message,
                        Toast.LENGTH_LONG).show();
            

            @Override
            public void onStart() 
                Toast.makeText(getApplicationContext(), "Started!",
                        Toast.LENGTH_LONG).show();
            

            @Override
            public void onFinish() 
                Toast.makeText(getApplicationContext(), "Stopped!",
                        Toast.LENGTH_LONG).show();
            
        );
     catch (FFmpegCommandAlreadyRunningException e) 

    

感谢您的帮助。

解决方案:

    我没有添加“加载二进制”部分,这是运行 FFmpeg 库 (http://writingminds.github.io/ffmpeg-android-java/)。 如 printfmyname 所述,该命令需要使用 .split(" "); 进行拆分 现在我使用 -vf crop=1080:1080:0:0 将视频裁剪为正方形。 (不搞乱比例)

【问题讨论】:

【参考方案1】:

我认为从 Ffmpeg 调用的 exec 命令需要一个字符串数组,所有参数都已标记化。尝试改变

final String[] cmd = new String[]"-i /storage/emulated/0/Alphacrypt1.mp4 -vf crop=640:256:0:400 -threads 5 -preset ultrafast -strict -2 /storage/emulated/0/YourCroppedMovie.mp4";

final String[] cmd = "-i /storage/emulated/0/Alphacrypt1.mp4 -vf crop=640:256:0:400 -threads 5 -preset ultrafast -strict -2 /storage/emulated/0/YourCroppedMovie.mp4".split(" ");

【讨论】:

谢谢老兄,解决了。我还必须添加 Load Binary 部分才能使用该库。 (检查writingminds.github.io/ffmpeg-android-java)。此外,您知道我现在如何将视频裁剪为方形格式吗? 您想通过裁剪(您将看到视频的一部分)使其成为方形视频还是通过填充视频使其成为方形?您还知道确切的源视频尺寸或宽高比吗? 好吧,我不确定我是否理解裁剪或填充的确切含义。请详细解释一下。是的,我知道有关源视频的所有必要信息,因为我之前录制过它。现在我使用了 -vf crop=1080:1080:0:0 的方法,这似乎效果很好。如果有更快的方法,如果你能告诉我,我会很高兴。也许还有一个替代方案。谢谢:)

以上是关于在 Android 中使用 FFmpeg 将视频裁剪为方形格式的主要内容,如果未能解决你的问题,请参考以下文章

android 中使用ffmpeg,将视频加入字幕,用ass文件,在PC上可以,但在Android上一直不行

ffmpeg命令将不同类型和分辨率的视频连接成1个视频,可以在android中播放[重复]

视频学习笔记:Android ffmpeg解码多路h264视频并显示

使用 FFMPEG 为 Android 转换视频

如何在android上使用ffmpeg录制视频?

如何在android中构建和使用ffmpeg