Problems with ffmpeg command line on android

2019-04-08 08:30发布

问题:

I managed to compile the ffmpeg Static build. But when I am trying to call the ffmpeg command line I get a Java IOException: No such file or Directory.

My code is as follows:

public void merge_video(View view){

    if(ffmpeg_file.exists()){
          Log.d(null, "ffmpeg exists");
      }else{
          Log.d(null, "Could not locate ffmpeg in the folder");
      }

      File file1 = new File("/mnt/sdcard/com.ffmpeg_test/VID_3_25_2013_12_22.mp4");
      if(file1.exists()){
          Log.d(null,"File 1 exists");
      }
      File file2 = new File("/mnt/sdcard/com.ffmpeg_test/VID_3_25_2013_12_28.mp4");
      if(file2.exists()){
          Log.d(null,"File 2 exists");
      }

      String[] ffmpegCommand = new String[5];
      ffmpegCommand[0] = "/mnt/sdcard/com.ffmpeg_test/ffmpeg";
      ffmpegCommand[1] = "-i";
      ffmpegCommand[2] = "concat:/mnt/sdcard/com.ffmpeg_test/VID_3_25_2013_12_22.mp4|/mnt/sdcard/com.ffmpeg_test/VID_3_25_2013_12_28.mp4";
      ffmpegCommand[3] = "copy";
      ffmpegCommand[4] = "/mnt/sdcard/com.ffmpeg_test/output.mp4";  

      try {
          Process ffmpegProcess = new ProcessBuilder(ffmpegCommand).redirectErrorStream(true).start();

          String line;
          BufferedReader reader = new BufferedReader(new InputStreamReader(ffmpegProcess.getInputStream()));
          Log.d(null, "*******Starting FFMPEG");

          while((line = reader.readLine())!=null){

              Log.d(null, "***"+line+"***"); 
          }
          Log.d(null,"****ending FFMPEG****");

    } catch (IOException e) {
        e.printStackTrace();
    }
  }

The LogCat print is as follows:

03-27 20:41:10.522: W/System.err(24709): java.io.IOException: Error running exec(). Command: [/mnt/sdcard/com.ffmpeg_test/ffmpeg, -i, concat:/mnt/sdcard/com.ffmpeg_test/VID_3_25_2013_12_22.mp4|/mnt/sdcard/com.ffmpeg_test/VID_3_25_2013_12_28.mp4, copy, /mnt/sdcard/com.ffmpeg_test/output.mp4] Working Directory: null Environment: [ANDROID_SOCKET_zygote=13, TMPDIR=/data/local/tmp, ANDROID_BOOTLOGO=1, EXTERNAL_STORAGE=/mnt/sdcard, ANDROID_ASSETS=/system/app, PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin, ASEC_MOUNTPOINT=/mnt/asec, LOOP_MOUNTPOINT=/mnt/obb, BOOTCLASSPATH=/system/framework/core.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/core-junit.jar, USBHOST_STORAGE=/mnt/sdcard/usbStorage, ANDROID_DATA=/data, LD_LIBRARY_PATH=/vendor/lib:/system/lib, ANDROID_ROOT=/system, ANDROID_PROPERTY_WORKSPACE=12,32768, EXTERNAL_STORAGE2=/mnt/sdcard/external_sd]
03-27 20:41:10.522: W/System.err(24709):    at java.lang.ProcessManager.exec(ProcessManager.java:224)
03-27 20:41:10.522: W/System.err(24709):    at java.lang.ProcessBuilder.start(ProcessBuilder.java:202)
03-27 20:41:10.522: W/System.err(24709):    at com.example.ffmpeg_test.MainActivity.merge_video(MainActivity.java:106)
03-27 20:41:10.522: W/System.err(24709):    at java.lang.reflect.Method.invokeNative(Native Method)
03-27 20:41:10.522: W/System.err(24709):    at java.lang.reflect.Method.invoke(Method.java:507)
03-27 20:41:10.527: W/System.err(24709):    at android.view.View$1.onClick(View.java:2149)
03-27 20:41:10.527: W/System.err(24709):    at android.view.View.performClick(View.java:2538)
03-27 20:41:10.527: W/System.err(24709):    at android.view.View$PerformClick.run(View.java:9152)
03-27 20:41:10.527: W/System.err(24709):    at android.os.Handler.handleCallback(Handler.java:587)
03-27 20:41:10.527: W/System.err(24709):    at android.os.Handler.dispatchMessage(Handler.java:92)
03-27 20:41:10.527: W/System.err(24709):    at android.os.Looper.loop(Looper.java:123)
03-27 20:41:10.527: W/System.err(24709):    at android.app.ActivityThread.main(ActivityThread.java:3691)
03-27 20:41:10.527: W/System.err(24709):    at java.lang.reflect.Method.invokeNative(Native Method)
03-27 20:41:10.527: W/System.err(24709):    at java.lang.reflect.Method.invoke(Method.java:507)
03-27 20:41:10.532: W/System.err(24709):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
03-27 20:41:10.532: W/System.err(24709):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
03-27 20:41:10.537: W/System.err(24709):    at dalvik.system.NativeStart.main(Native Method)
03-27 20:41:10.537: W/System.err(24709): Caused by: java.io.IOException: No such file or directory
03-27 20:41:10.537: W/System.err(24709):    at java.lang.ProcessManager.exec(Native Method)
03-27 20:41:10.537: W/System.err(24709):    at java.lang.ProcessManager.exec(ProcessManager.java:222)
03-27 20:41:10.537: W/System.err(24709):    ... 16 more
03-27 20:41:36.057: W/KeyCharacterMap(24709): No keyboard for id 0
03-27 20:41:36.057: W/KeyCharacterMap(24709): Using default keymap: /system/usr/keychars/qwerty.kcm.bin

回答1:

Android has a special security feature: the /mnt/sdcard filesystem is execution-protected. You cannot run an executable that is located on the external storage (a.k.a. USB storage). If you want to run ffmpeg binary on your device, you must load it into one of the internal directories. For example, you can pack it into libs/armeabi of your Java project, so that the installer will automatically unpack it into the /data/data/<your package>/lib directory on the device. Or you can find another directory, like /data/local, where you can put the executable binary file with adb push