加载所需的库时无法链接可执行错误。如何正确链接它们?

den*_*tex 2 java android ffmpeg libs android-native-library

编辑:我知道可能重复,但答案不直接适用。我正在使用 ProcessBuilder 而不是 Runtime.getRuntime().exec:

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;
}
Run Code Online (Sandbox Code Playgroud)

我在为 android 编译的 FFmpeg 上有两个版本:liblame启用和不启用。

当我加载/data/data/<<my-package-name>>/app_bin/没有跛脚支持编译的 FFmpeg 二进制文件时,它可以毫无问题地从视频中提取音频。但是当我使用启用了跛脚支持的那个时,我在日志中收到以下错误。

所需的库,也是为 android 编译的,在libs使用System.loadLibrary("lame").

我想知道是否还有其他事情要做才能正确地使 FFmpeg 二进制文件找到库。这些是提供给 NDK 以构建 FFmpeg 二进制文件的相同库。

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
Run Code Online (Sandbox Code Playgroud)

我没有附上代码,因为它相当简单:

  • 下载 FFmpeg 二进制文件(它不随应用程序一起提供);
  • 将二进制文件从下载文件夹复制到/data/data/<<my-package-name>>/app_bin/
  • chmod 755;
  • 从那里执行并读取输出。

如果需要其他东西,请发表评论。

den*_*tex 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>>/");
Run Code Online (Sandbox Code Playgroud)

或者,更好的是避免在包名称(更改)之后处理“-1”或“-2”后缀:

2)

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

并且不要硬编码/data/data/<<my-pkg-name>>/lib 使用:Context.getApplicationInfo().nativeLibraryDir

有了这个解决方案2)我还发现,System.loadLibrary("lame")不是必要的。