Android - Ошибка при выполнении Runtime.getRuntime().exec() - Environment Null -ffmpeg

Я скомпилировал библиотеку ffmpeg на Ubuntu 11.10 и перенес скомпилированные файлы на Android.
После компиляции я успешно получил libffmpeg.so. Он успешно загружается на Android.

Я делаю это на эмуляторе Android ubuntu 11.10 eclipse.

Я создал небольшое тестовое приложение, которое действует как командная строка, которая принимает команду от пользователя и отображает результат. (тестирование команд ffmpeg)

Когда я запускаю простые команды, такие как «ls», «ls -l», все работает отлично. но когда я просто набираю "cd mnt" или "ffmpeg" в качестве команды и пытаюсь ее запустить. Я получил Предупреждения в Logcat о том, что

08-26 16:44:52.553: W/System.err(5961): java.io.IOException: Error running exec(). Command: [ffmpeg] Working Directory: null Environment: null
08-26 16:44:52.573: W/System.err(5961):     at java.lang.ProcessManager.exec(ProcessManager.java:211)
08-26 16:44:52.573: W/System.err(5961):     at java.lang.Runtime.exec(Runtime.java:168)
08-26 16:44:52.573: W/System.err(5961):     at java.lang.Runtime.exec(Runtime.java:241)
08-26 16:44:52.583: W/System.err(5961):     at java.lang.Runtime.exec(Runtime.java:184)
08-26 16:44:52.593: W/System.err(5961):     at ch.ffmpeg.reversit.MainActivity.Execute(MainActivity.java:61)
08-26 16:44:52.593: W/System.err(5961):     at ch.ffmpeg.reversit.MainActivity$1.onClick(MainActivity.java:46)
08-26 16:44:52.593: W/System.err(5961):     at android.view.View.performClick(View.java:3480)
08-26 16:44:52.593: W/System.err(5961):     at android.view.View$PerformClick.run(View.java:13983)
08-26 16:44:52.603: W/System.err(5961):     at android.os.Handler.handleCallback(Handler.java:605)
08-26 16:44:52.603: W/System.err(5961):     at android.os.Handler.dispatchMessage(Handler.java:92)
08-26 16:44:52.603: W/System.err(5961):     at android.os.Looper.loop(Looper.java:137)
08-26 16:44:52.614: W/System.err(5961):     at android.app.ActivityThread.main(ActivityThread.java:4340)
08-26 16:44:52.624: W/System.err(5961):     at java.lang.reflect.Method.invokeNative(Native Method)
08-26 16:44:52.624: W/System.err(5961):     at java.lang.reflect.Method.invoke(Method.java:511)
08-26 16:44:52.634: W/System.err(5961):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
08-26 16:44:52.634: W/System.err(5961):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
08-26 16:44:52.644: W/System.err(5961):     at dalvik.system.NativeStart.main(Native Method)
08-26 16:44:52.644: W/System.err(5961): Caused by: java.io.IOException: Permission denied
08-26 16:44:52.674: W/System.err(5961):     at java.lang.ProcessManager.exec(Native Method)
08-26 16:44:52.674: W/System.err(5961):     at java.lang.ProcessManager.exec(ProcessManager.java:209)
08-26 16:44:52.684: W/System.err(5961):     ... 16 more

Вот мой код:

imports;
public class MainActivity extends Activity {
    String com;
    Process process;
    EditText command;
    Button run;
    RelativeLayout main_layout;

    static {
     System.loadLibrary("ffmpeg");
    }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

       //find view 
       command=(EditText)findViewById(R.id.command);
       run=(Button)findViewById(R.id.run);

        run.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                com=command.getText().toString();
                try {
                    Execute();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        }); 

    }

    public void Execute() throws IOException, InterruptedException{
        process=Runtime.getRuntime().exec(com);
        // process = pb.command(com).redirectErrorStream(true).start();

        if(process!=null)
        ShowOutput();
        else
        Toast.makeText(getBaseContext(),"Null Process",Toast.LENGTH_LONG).show();
    }

    public void ShowOutput() throws IOException, InterruptedException{
        String s,text="",errors="";
        BufferedReader stdInput = new BufferedReader(new 
                InputStreamReader(process.getInputStream()));

           BufferedReader stdError = new BufferedReader(new 
                InputStreamReader(process.getErrorStream()));


           TextView output=(TextView)findViewById(R.id.output);
           TextView error=(TextView)findViewById(R.id.error);

            while ((s = stdInput.readLine()) != null) {
                   text+=s.toString()+"\n";
                   System.out.println("Error: "+s);
               }

         output.setText(text);
         text="";
           // read any errors from the attempted command
           System.out.println("Here is the standard error of the command (if any):\n");
           while ((s = stdError.readLine()) != null) {
               text+=s.toString()+"\n";
               System.out.println("Error: "+s);
           }

           error.setText(text);

           error.setMovementMethod(new ScrollingMovementMethod());
           output.setMovementMethod(new ScrollingMovementMethod());

           stdInput.close();
           stdError.close();

           process.waitFor();
           process.getOutputStream().close();
           process.getInputStream().close();
           process.getErrorStream().close(); 
           process.destroy();


    }

}

Я даже пробовал process = pb.command(com).redirectErrorStream(true).start(); для казни. Это дает мне ту же ошибку, но на этот раз среда была [ANDROID_SOCKET_Zygot] bla bla bla..


EDIT 1: я использую Openjdk на Ubuntu

Помоги мне !!


person Chaitanya Chandurkar    schedule 26.08.2012    source источник


Ответы (3)


Существует довольно большое количество обсуждений [android] [ffmpeg] и способов...

Обычный способ вызвать ffmpeg на некорневых устройствах (т. е. приложение для обычных пользователей) — это использовать NDK и интеграцию с C-lang, где в java вы делаете обычный вызов метода, который обертывает материал CLI и набор параметров, которые Уровень JNI будет доставляться на интерфейс исполняемого файла ffmpeg.

Пример вызова android step1.android будет...

             new FFMpegTask().execute(invoke_lib_path,"ffmpeg", "-y", 
                    "-i", Picture.getPath(), "-i", recordFilePath,
                    "-vcodec", "mpeg4", "-s", siz,
                    "-r", "15", "-b:v", "200k",
                    "-acodec", "copy", "-f", "3gp"
                    ,pathOut);

Шаг 2.с

JNIEXPORT void JNICALL Java_com_..._naRun( JNIEnv *env, объект задания, аргументы jobjectArray) { int i = 0; интервал аргумент = 0; char **argv = NULL;

if (args != NULL) { argc = (env)->GetArrayLength(env, args); argv = (char *) malloc(sizeof(char *) * argc);

  for(i=0;i<argc;i++)         {           jstring str =

(jstring)(*env)->GetObjectArrayElement(env, args, i); argv[i] = (char *)(*env)->GetStringUTFChars(env, str, NULL); } } интервал j = 0; j = основной (argc, argv); }

Попытка использовать вызов CLI типа java runtime.exec() - это то, что я бы назвал взломом, который будет большой тратой вашего времени.

Используя NDK и обычную упаковку в .apk, вы обеспечиваете более высокую степень надежности и интеграции между такими вещами, как архитектура процессора на устройстве развертывания и процессором, для которого был создан ffmpeg.

попробуйте прочитать введение roman10

Тогда вы можете попробовать положиться на хлебные крошки от многих людей, которые построили ffmpeg для Android .. т.е. Google "android-ffmpeg"

Если у вас есть root-права и вы скомпилировали исполняемый файл, вы можете вызвать его, получив оболочку и используя интерфейс командной строки adb. Обратите внимание, что это не похоже на использование java в качестве оболочки для вызовов runtime.exec.

adb push ffmpeg /data/local/ffmpeg/ffmpeg

./ffmpeg -кодеки

person Robert Rowntree    schedule 26.08.2012
comment
да. например, вы можете просто получить код по ссылке, упомянутой в блоге roman10. на github есть много других, более новых проектов android-ffmpeg. просто найдите там android-ffmpeg. Вы можете клонировать один из них и собрать его, следуя инструкциям в README. - person Robert Rowntree; 27.08.2012
comment
из какого каталога я должен запускать adb push ffmpeg?? я не нашел свои двоичные файлы ffmpeg через adb. Можете ли вы сказать мне, где я могу найти его? - person Chaitanya Chandurkar; 28.08.2012
comment
Project$ ls -l libs/armeabi-v7a/ есть в моей системе. Ваша цепочка инструментов определяет выходное местоположение. если вы используете NDK, прочитайте документы в ./docs. Если вы используете ndk, добавьте V=1 -B - person Robert Rowntree; 28.08.2012
comment
хорошо, в моем случае lib/armeabi-v7a содержит только файл libffmpeg.so. так что мне нужно, чтобы целые двоичные файлы (папка ffmpeg) были вставлены правильно? - person Chaitanya Chandurkar; 28.08.2012
comment
Ok. ваш файл Android.mk создает только общие модули. измените его, чтобы создать исполняемый файл, а затем вы найдете его в папке, которую вы упомянули. РТМ... - person Robert Rowntree; 28.08.2012

Насколько я знаю, вы не можете использовать команду cd. Это директива bash, исполняемого компакт-диска нет. Я думаю, ffmpeg не работает из-за разрешений. В оболочке adb выполните chmod 777 ffmpeg и повторите попытку.

person nandeesh    schedule 26.08.2012
comment
эй .. не могли бы вы сказать мне, для какого каталога или библиотеки я должен запустить эту команду. Я пробовал из оболочки adb, но он говорит, что такого каталога нет. - person Chaitanya Chandurkar; 26.08.2012
comment
найдите, где присутствует ffmpeg, он может быть в system/bin, так что вы можете пойти туда и сделать это. Даже в коде используйте /system/bin/ffmpeg - person nandeesh; 26.08.2012
comment
я искал !! но нет каталога с именем ffmpeg. ffmpeg на самом деле является родной библиотекой. я скомпилировал libffmpeg.so, который должен был дать мне поддержку ffmpeg. - person Chaitanya Chandurkar; 26.08.2012
comment
github.com/halfninja/android-ffmpeg- x264/blob/master/Project/ посмотрите на строки различий (18 против 34) . Если вам нужен исполняемый файл, укажите это. Если вам нужна общая библиотека, укажите это.... прочитайте документы на Android.mk в ./NDK_ROOT/docs - person Robert Rowntree; 31.08.2012

я могу немного опоздать

java.io.IOException: Error running exec(). Command: [ffmpeg] Working Directory: null Environment: null

Четко указано, что файл ffmpeg не найден. Перед выполнением любой команды сначала проверьте, присутствует ли файл в указанном месте.

boolean ifFileExists = new File(*path_of_ffmpeg_file*).exists();


       if(ifFileExists==false){
// code to write file in phone
    }
method(commandToExecute);
person Gaganpreet Singh    schedule 18.02.2015