Android NDK& FFMPEG:findLibrary返回null

时间:2015-02-20 09:31:39

标签: android android-ndk ffmpeg

我正在使用它在ndk上构建ffmpeg: roman10's android ndk r9d - ffmpeg tutorial

该链接显示了如何编译,但不清楚如何使用它。任何人都可以指导我吗?感谢。

从我的项目根目录进行ndk-build后,我能够在libs/armeabiobj/local/armeabi内生成.so文件。现在我正在 findLibrary returned null ? ?现在做什么?

java.lang.UnsatisfiedLinkError: Couldn't load libavutil from loader dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.palak.androidffmpegroman-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.palak.androidffmpegroman-2, /vendor/lib, /system/lib]]]: findLibrary returned null

        at java.lang.Runtime.loadLibrary(Runtime.java:358)
        at java.lang.System.loadLibrary(System.java:526)
        at com.palak.androidffmpegroman.MainActivity.<clinit>(MainActivity.java:175)
        at java.lang.Class.newInstanceImpl(Native Method)
        at java.lang.Class.newInstance(Class.java:1208)
        at android.app.Instrumentation.newActivity(Instrumentation.java:1061)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2101)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
        at android.app.ActivityThread.access$800(ActivityThread.java:135)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5001)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
        at dalvik.system.NativeStart.main(Native Method)

我的项目结构:

enter image description here

我的build_android.sh

  #!/bin/bash
NDK=$HOME/NDK/android-ndk-r10d
SYSROOT=$NDK/platforms/android-19/arch-arm/
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86
function build_one
{
sudo ./configure \
    --prefix=$PREFIX \
    --enable-shared \
    --disable-static \
    --disable-doc \
    --disable-ffmpeg \
    --disable-ffplay \
    --disable-ffprobe \
    --disable-ffserver \
    --disable-avdevice \
    --disable-doc \
    --disable-symver \
    --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
    --target-os=linux \
    --arch=arm \
    --enable-cross-compile \
    --sysroot=$SYSROOT \
    --extra-cflags="-Os -fpic $ADDI_CFLAGS" \
    --extra-ldflags="$ADDI_LDFLAGS" \
    $ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
}
CPU=arm
PREFIX=$(pwd)/android/$CPU 
ADDI_CFLAGS="-marm"
build_one

我正在使用Ndk r10,ffmpeg 2.5.4,ubuntu x86。

编辑:Android.mk

LOCAL_PATH:= /home/palak/NDK/ffmpeg-2.5.4/android/arm

include $(CLEAR_VARS)
LOCAL_MODULE:= libavcodec
LOCAL_SRC_FILES:= lib/libavcodec-56.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= libavformat
LOCAL_SRC_FILES:= lib/libavformat-56.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= libswscale
LOCAL_SRC_FILES:= lib/libswscale-3.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= libavutil
LOCAL_SRC_FILES:= lib/libavutil-54.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= libavfilter
LOCAL_SRC_FILES:= lib/libavfilter-5.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE:= libswresample
LOCAL_SRC_FILES:= lib/libswresample-1.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)

在jni文件夹下的Android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := tutorial01
LOCAL_SRC_FILES := tutorial01.c
LOCAL_LDLIBS := -llog -ljnigraphics -lz 
LOCAL_SHARED_LIBRARIES := avformat avcodec swscale avutil

include $(BUILD_SHARED_LIBRARY)
$(call import-module,ffmpeg-2.5.4/android/arm)

4 个答案:

答案 0 :(得分:1)

替换

LOCAL_SHARED_LIBRARIES := avformat avcodec swscale avutil 

LOCAL_SHARED_LIBRARIES := libavformat libavcodec libswscale libavutil libavfilter libswresample 
在您的Jni文件夹中的Android.mk中

并按如下所示加载库

static {

  System.loadLibrary("avutil-54");
  System.loadLibrary("avcodec-56");
  System.loadLibrary("avformat-56");
  System.loadLibrary("swscale-3");
  System.loadLibrary("avfilter-5");
  System.loadLibrary("swresample-1");
  System.loadLibrary("tutorial01");

}

答案 1 :(得分:0)

LOCAL_MODULE:= libavutil

- &GT;

LOCAL_MODULE:= avutil # libavutil.so

示例(用于工作): https://github.com/18446744073709551615/reDroid/blob/master/jni/Android.mk

<强>更新
再一次:您不需要库名称中的lib前缀;左LOCAL_MODULE:= avutil将为您提供 lib avutil .so

第二,你传递给 loadLibrary()的参数是什么?对于 lib avutil .so ,它应该是"avutil"

如果您遇到问题,最好的方法是从NDK中的hello-jni示例开始( your-ndk-dir /samples/hello-jni/

/* this is used to load the 'hello-jni' library on application
 * startup. The library has already been unpacked into
 * /data/data/com.example.hellojni/lib/libhello-jni.so <== !!!!!!!!!!!!!
 * at installation time by the package manager.
 */
static {
    System.loadLibrary("hello-jni");
}

一旦示例编译并运行,您可以将库添加到其中并使您的工作正常工作。

答案 2 :(得分:0)

ndk-build 期间,您使用名称libavutil来引用libavutil-54.so。这很好,但运行时库仍称为 libavutil-54.so 。此外,您的其他模块(包括tutorial01)通过此名称了解它,因此在libs/armeabi中重命名也将是错误的。

你需要像

这样的东西
static {
    System.loadLibrary("avutil-54");
    System.loadLibrary("avcodec-56");
    System.loadLibrary("avformat-56");
    System.loadLibrary("swscale-3");
    System.loadLibrary("tutorial01");
}

在Android的最新版本中,系统会自动解析本地外部引用,因此只需调用

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

答案 3 :(得分:0)

您确定使用的是带有armeabi处理器的手机吗?在Application.mk文件中添加armeabiv7,它将在libs文件夹中编译armeabiv7手机所需的文件。

APP_ABI := armeabi armeabi-v7a x86

这应该有用。