2

編集:重複の可能性は認識していますが、その答えは直接適用できません。Runtime.getRuntime().exec ではなく ProcessBuilder を使用しています。

public int execProcess(List<String> cmds, ShellUtils.ShellCallback sc) {    
    StringBuilder cmdlog = new StringBuilder();
    for (String cmd : cmds) {
         cmdlog.append(' ');
    }
    Utils.logger("v", cmdlog.toString(), DEBUG_TAG);

    ProcessBuilder pb = new ProcessBuilder();
    pb.directory(mBinFileDir);
    pb.command(cmds);

    Process process = null;
    int exitVal = 1; // Default error
    try {
        process = pb.start();

        StreamGobbler errorGobbler = new
        StreamGobbler(process.getErrorStream(), "ERROR", sc);

        StreamGobbler outputGobbler = new
        StreamGobbler(process.getInputStream(), "OUTPUT", sc);

        errorGobbler.start();
        outputGobbler.start();

        exitVal = process.waitFor();

        sc.processComplete(exitVal);

     } catch (Exception e) {
         Log.e(DEBUG_TAG, "Error executing ffmpeg command!", e);
     } finally {
         if (process != null) {
             Utils.logger("w", "destroyng process", DEBUG_TAG);
             process.destroy();
         }
    }
    return exitVal;
}

Android用にコンパイルされたFFmpegには、有効なバージョンとliblame有効でないバージョンの2つのバージョンがあります。

/data/data/<<my-package-name>>/app_bin/ラメ サポートなしでコンパイルされた FFmpeg バイナリを読み込むと、問題なくビデオからオーディオが抽出されます。しかし、ラメサポートを有効にして使用すると、以下のエラーがログに記録されます。

必要なライブラリも Android 用にコンパイルされており、libsプロジェクト フォルダにSystem.loadLibrary("lame").

FFmpeg バイナリがライブラリを適切に検出できるようにするために他に何かすべきことがあるかどうか疑問に思っていました。これらは、FFmpeg バイナリをビルドするために NDK に指定されたものと同じライブラリです。

D/dalvikvm(13741): Trying to load lib /data/app-lib/<<my-package-name>>/liblame.so 0x40ffed08
D/dalvikvm(13741): Added shared lib /data/app-lib/<<my-package-name>>/liblame.so 0x40ffed08
D/dalvikvm(13741): No JNI_OnLoad found in /data/app-lib/<<my-package-name>>/liblame.so 0x40ffed08, skipping init
D/FfmpegController(13741): Trying to chmod '/data/data/<<my-package-name>>/app_bin/ffmpeg' to: 755
V/FfmpegController(13741): /data/data/<<my-package-name>>/app_bin/ffmpeg -y -i /storage/sdcard0/Download/video.webm -vn -acodec copy /storage/sdcard0/Download/audio.ogg 
>>>>>> ---------- <<<<<<
D/DownloadsService(13741): soinfo_link_image(linker.cpp:1673): could not load library "liblame.so" needed by "/data/data/<<my-package-name>>/app_bin/ffmpeg"; caused by load_library(linker.cpp:771): library "liblame.so" not foundCANNOT LINK EXECUTABLE
>>>>>> ---------- <<<<<<
I/DownloadsService(13741): FFmpeg process exit value: 255

かなり簡単なので、コードは添付しません。

  • FFmpeg バイナリをダウンロードします (アプリには同梱されていません)。
  • バイナリをダウンロード フォルダから にコピーします/data/data/<<my-package-name>>/app_bin/
  • chmod 755;
  • そこから実行し、出力を読み取ります。

他に何か必要な場合はコメントしてください。

4

1 に答える 1

5

最近、すべての答えを見つけているのはおかしいです...とにかく、必要に応じて、他の人に役立つ可能性があるためです。

  • のような共有ライブラリのパスを追加しますliblame.so
  • フォルダSystem.loadLibrary("lame")からロードlibs
  • そしてあなたは使いたいProcessBuilder

する

1)

ProcessBuilder pb = new ProcessBuilder("liblame.so");
Map<String, String> envMap = pb.environment();
envMap.put("LD_LIBRARY_PATH", "/data/app-lib/<<my-pkg-name>>/");

または、パッケージ名の後に「-1」または「-2」サフィックスを処理しないようにすることをお勧めします (変更されます)。

2)

ProcessBuilder pb = new ProcessBuilder();
Map<String, String> envMap = pb.environment();
envMap.put("LD_LIBRARY_PATH", "/data/data/<<my-pkg-name>>/lib");

また、使用をハードコーディングしないで/data/data/<<my-pkg-name>>/lib ください:Context.getApplicationInfo().nativeLibraryDir

このソリューションでは、2)必要がないSystem.loadLibrary("lame")こともわかりました。

于 2013-04-03T12:55:20.703 に答える