FFmpeg android execute

2019-08-10 09:46发布

问题:

On windows I could cut a video with below code with ffmpeg.exe

Can't use ffmpeg in android. I used gradle to grab ffmpeg in my app.

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.github.hiteshsondhi88.libffmpeg:FFmpegAndroid:0.2.5'
}

I have these lines in my method

VideoIn = getInternalDirectoryPath() + "/Download/Ab.mp4";
VideoOut = getInternalDirectoryPath() + "/Download/Ab1.mp4";

try {
ffmpeg.execute("ffmpeg -i " + VideoIn + " -ss 00:00:03 -c:v libx264 -crf 17 -t 00:00:5 " + VideoOut + " -y",null);
}
catch (FFmpegCommandAlreadyRunningException e) { 
e.printStackTrace();
}

Shows this error: Error running exec(). Command: [/data/data/com.videoeditor.myname.myapp/files/ffmpeg, ffmpeg, -i, /storage/emulated/0/Download/Ab.mp4, -ss, 00:00:03, -c:v, libx264, -crf, 17, -t, 00:00:5, /storage/emulated/0/Download/Ab1.mp4, -y] Working Directory: null Environment: null

What's wrong with this method? Thanks for your help

回答1:

Ok I found the answer: There is no need for "ffmpeg" in cmd with this method of using ffmpeg

Simple video cut example:

 /**
 * Returns the path to internal storage ex:- /storage/emulated/0
 *
 * @return
 */
private String getInternalDirectoryPath() {
    return Environment.getExternalStorageDirectory().getAbsolutePath();
}

VideoIn = getInternalDirectoryPath() + "/Download/Ab.mp4";
VideoOut = getInternalDirectoryPath() + "/Download/Ab1.mp4";

private void CutVideo(){
try {
     ffmpeg.execute("-i "+VideoIn+" -ss 00:01:00 -to 00:02:00 -c copy "+VideoOut ,
new ExecuteBinaryResponseHandler() {

                @Override
                public void onStart() {
                //for logcat
                    Log.w(null,"Cut started");
                }

                @Override
                public void onProgress(String message) {
                //for logcat
                    Log.w(null,message.toString());
                }

                @Override
                public void onFailure(String message) {

                    Log.w(null,message.toString());
                }

                @Override
                public void onSuccess(String message) {

                    Log.w(null,message.toString());
                }

                @Override
                public void onFinish() {

                    Log.w(null,"Cutting video finished");
                }
            });
        } catch (FFmpegCommandAlreadyRunningException e) {
            // Handle if FFmpeg is already running
            e.printStackTrace();
            Log.w(null,e.toString());
        }
}


回答2:

Ok. Your problem is that you aren't loading the ffmpeg binary. You have to load it before executing the command. Try something like this:

private FFmpeg ffmpeg;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    FFmpeg ffmpeg = FFmpeg.getInstance(this);
    try {
        //Load the binary
        ffmpeg.loadBinary(new LoadBinaryResponseHandler() {

            @Override
            public void onStart() {}

            @Override
            public void onFailure() {}

            @Override
            public void onSuccess() {}

            @Override
            public void onFinish() {}
        });
    } catch (FFmpegNotSupportedException e) {
        // Handle if FFmpeg is not supported by device
    }
    try {
        // to execute "ffmpeg -version" command you just need to pass "-version" 
        // Now, you can execute your command here
        ffmpeg.execute("ffmpeg -version", new ExecuteBinaryResponseHandler() {

            @Override
            public void onStart() {}

            @Override
            public void onProgress(String message) {}

            @Override
            public void onFailure(String message) {}

            @Override
            public void onSuccess(String message) {
                Log.i("SUCCESS", message);
            }

            @Override
            public void onFinish() {}
        });
    } catch (FFmpegCommandAlreadyRunningException e) {
        // Handle if FFmpeg is already running
    }
}

More info on http://hiteshsondhi88.github.io/ffmpeg-android-java/



回答3:

You need to read process's error stream to figure out what is wrong:

InputStreamReader errReader = new InputStreamReader(process.getErrorStream());
BufferedReader bufReader = new BufferedReader(errReader);
while ((String line = bufReader.readLine()) != null) {
    Log.d("MyApp", line);
}

But I suppose problem is in wrong argument for exec method, if you need to run both chmod and ffmpeg, you should probably use exec(String[] progArray, String[] envp)