我使用bambuser的文件编译了FFMPEG for
android.编译运行正常.没有错误.
我还确保在build.sh中更改包名称.但是,一旦我尝试链接到文件,手机就会抛出UnsatisfiedLinkError.这是Androkd.mk文件:
我还确保在build.sh中更改包名称.但是,一旦我尝试链接到文件,手机就会抛出UnsatisfiedLinkError.这是Androkd.mk文件:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) MY_LIB_PATH := ffmpeg-android/build/ffmpeg/armeabi/lib LOCAL_MODULE := bambuser-libavcore LOCAL_SRC_FILES := $(MY_LIB_PATH)/libavcore.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := bambuser-libavformat LOCAL_SRC_FILES := $(MY_LIB_PATH)/libavformat.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := bambuser-libavcodec LOCAL_SRC_FILES := $(MY_LIB_PATH)/libavcodec.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := bambuser-libavdevice LOCAL_SRC_FILES := $(MY_LIB_PATH)/libavdevice.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := bambuser-libavfilter LOCAL_SRC_FILES := $(MY_LIB_PATH)/libavfilter.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := bambuser-libavutil LOCAL_SRC_FILES := $(MY_LIB_PATH)/libavutil.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := bambuser-libswscale LOCAL_SRC_FILES := $(MY_LIB_PATH)/libswscale.so include $(PREBUILT_SHARED_LIBRARY) #local_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libtest_jni LOCAL_SRC_FILES := libtest/video.c LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/include \ $(LOCAL_PATH)/ffmpeg-android/ffmpeg LOCAL_LDLIBS := -L$(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-arm/usr/lib -L$(LOCAL_PATH) -L$(LOCAL_PATH)/ffmpeg-android/build/ffmpeg/armeabi/lib/ -lavformat -lavcodec -lavdevice -lavfilter -lavutil -lswscale -llog -lz -lm #dl -lgcc include $(BUILD_SHARED_LIBRARY)
Video.c很简单:
#include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libswscale/swscale.h> #include <jni.h> #include <string.h> #include <stdio.h> #include <android/log.h> void Java_com_bukabros_videolivewallpaper_Opengl2Renderer_loadNthFrame3 (JNIEnv * env,jobject this,jstring fileName) { jboolean isCopy; const char * szLogThis = (*env)->GetStringUTFChars(env,fileName,&isCopy); __android_log_print(ANDROID_LOG_DEBUG,"NDK: ","NDK:LC: [%s]",szLogThis); }
相应的Java代码也很简单:
private native void loadNthFrame3(String fileName); static { System.loadLibrary("libtest_jni"); }
但我得到这个错误:
E/AndroidRuntime(11489): FATAL EXCEPTION: main E/AndroidRuntime(11489): java.lang.ExceptionInInitializerError E/AndroidRuntime(11489): at com.bukabros.videolivewallpaper.VideoLiveWallpaper$CubeEngine.<init>(VideoLiveWallpaper.java:147) E/AndroidRuntime(11489): at com.bukabros.videolivewallpaper.VideoLiveWallpaper.onCreateEngine(VideoLiveWallpaper.java:120) E/AndroidRuntime(11489): at android.service.wallpaper.WallpaperService$IWallpaperEngineWrapper.executeMessage(WallpaperService.java:814) E/AndroidRuntime(11489): at com.android.internal.os.HandlerCaller$MyHandler.handleMessage(HandlerCaller.java:61) E/AndroidRuntime(11489): at android.os.Handler.dispatchMessage(Handler.java:99) E/AndroidRuntime(11489): at android.os.Looper.loop(Looper.java:123) E/AndroidRuntime(11489): at android.app.ActivityThread.main(ActivityThread.java:4627) E/AndroidRuntime(11489): at java.lang.reflect.Method.invokeNative(Native Method) E/AndroidRuntime(11489): at java.lang.reflect.Method.invoke(Method.java:521) E/AndroidRuntime(11489): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878) E/AndroidRuntime(11489): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636) E/AndroidRuntime(11489): at dalvik.system.NativeStart.main(Native Method) E/AndroidRuntime(11489): Caused by: java.lang.UnsatisfiedLinkError: Library libtest_jni not found E/AndroidRuntime(11489): at java.lang.Runtime.loadLibrary(Runtime.java:461) E/AndroidRuntime(11489): at java.lang.System.loadLibrary(System.java:557) E/AndroidRuntime(11489): at com.bukabros.videolivewallpaper.Opengl2Renderer.<clinit>(Opengl2Renderer.java:389) E/AndroidRuntime(11489): ... 12 more
我尝试用Java手动加载预构建的共享库(bambuser文件)(使用System.loadLibrary),但它告诉我找不到文件.
如果它有帮助,这里是readelf的输出:
0x00000001 (NEEDED) Shared library: [libc.so] 0x00000001 (NEEDED) Shared library: [libstdc++.so] 0x00000001 (NEEDED) Shared library: [libm.so] 0x00000001 (NEEDED) Shared library: [/data/data/com.bukabros.videolivewallpaper/lib/libavformat.so] 0x00000001 (NEEDED) Shared library: [/data/data/com.bukabros.videolivewallpaper/lib/libavcodec.so] 0x00000001 (NEEDED) Shared library: [/data/data/com.bukabros.videolivewallpaper/lib/libavdevice.so] 0x00000001 (NEEDED) Shared library: [/data/data/com.bukabros.videolivewallpaper/lib/libavfilter.so] 0x00000001 (NEEDED) Shared library: [/data/data/com.bukabros.videolivewallpaper/lib/libavutil.so] 0x00000001 (NEEDED) Shared library: [/data/data/com.bukabros.videolivewallpaper/lib/libswscale.so] 0x00000001 (NEEDED) Shared library: [liblog.so] 0x00000001 (NEEDED) Shared library: [libz.so] 0x00000001 (NEEDED) Shared library: [libdl.so] 0x0000000e (SONAME) Library soname: [libtest_jni.so] 0x00000010 (SYMBOLIC) 0x0 0x00000004 (HASH) 0xd4 0x00000005 (STRTAB) 0x250 0x00000006 (SYMTAB) 0x130 0x0000000a (STRSZ) 712 (bytes) 0x0000000b (SYMENT) 16 (bytes) 0x00000003 (PLTGOT) 0x174c 0x00000002 (PLTRELSZ) 32 (bytes) 0x00000014 (PLTREL) REL 0x00000017 (JMPREL) 0x55c 0x6ffffffe (VERNEED) 0x53c 0x6fffffff (VERNEEDNUM) 1 0x6ffffff0 (VERSYM) 0x518 0x00000000 (NULL) 0x0
哦耶.我正在使用ndk r5.
解决方法
看起来我找到了答案.问题是当您使用Java(System.loadLibrary)加载库时,不能使用“lib”前缀.我还必须在Java中手动加载ffmpeg库.故事的寓意是你应该总是阅读文档,不要放弃:-)这是正确的代码:
static { System.loadLibrary("avcore"); System.loadLibrary("avformat"); System.loadLibrary("avcodec"); System.loadLibrary("avdevice"); System.loadLibrary("avfilter"); System.loadLibrary("avutil"); System.loadLibrary("swscale"); System.loadLibrary("test_jni"); }