由于这是该问题的热门话题,并且问题本身仍然存在,因此 ZakiMak 与我们分享的方法似乎仍然是最受欢迎的解决方案。
对于其他可能想要实现它并希望了解最新 Android 版本的更多详细信息的人,以下是我在偶然发现时做的一些笔记:
- 首先,现在有一个在 GitHub 上实现这种方法的解决方案。我没有亲自尝试过,但我已将其用作参考。查看 Android.mk 文件的结构以及库的打开方式和方法调用方式非常有用。链接在这里:https ://github.com/jhotovy/android-ffmpeg
- 本机库文件夹的路径会随着 Android 版本的变化而变化,并且每次运行应用程序时它似乎也会发生变化(尽管这可能只是处于调试模式)。无论哪种方式,如果可能,最好从调用 Java 方法传入路径。例如:
在 Java 包装类中:
import android.content.Context;
import android.util.Log;
public class FfmpegJNIWrapper {
//This class provides a Java wrapper around the exposed JNI ffmpeg functions.
static {
//Load the 'first' or 'outer' JNI library so this activity can use it
System.loadLibrary("ffmpeg_wraper_multi_invoke_jni");
}
public static int call_ffmpegWrapper(Context appContext, String[] ffmpegArgs) {
//Get the native libary path
String nativeLibPath = appContext.getApplicationInfo().nativeLibraryDir;
//Call the method in the first or 'outer' library, passing it the
//native library past as well as the original args
return ffmpegWrapper(nativeLibPath, ffmpegArgs);
}
// Native methods for ffmpeg functions
public static native int ffmpegWrapper(String nativeLibPath, String[] argv);
}
在“第一”或“外部”本机库中:
JNIEXPORT jint JNICALL Java_com_yourpackage_androidffmpegwrapper_FfmpegJNIWrapper_ffmpegWrapper(JNIEnv *pEnv, jobject pObj, jstring nativeLibPath, jobjectArray javaArgv) {
//Get the second or 'inner' native library path
char* nativePathPassedIn = (char *)(*pEnv)->GetStringUTFChars(pEnv, nativeLibPath, NULL);
char ourNativeLibraryPath[256];
snprintf(ourNativeLibraryPath, sizeof (ourNativeLibraryPath), "%s%s", nativePathPassedIn, "/libffmpeg_wraper_jni.so"); //the name of your ffmpeg library
//Open the so library
void *handle;
typedef int (*func)(JNIEnv*, jobject, jobjectArray);
handle = dlopen(ourNativeLibraryPath, RTLD_LAZY);
if (handle == NULL) {
__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "could not open library: %s", dlerror());
printf("Could not dlopen(\"libbar.so\"): %s\n", dlerror());
return(-1);
}
//Call the ffmpeg wrapper functon in the second or 'inner' library
func reenterable_ffmpegWrapperFunction;
reenterable_ffmpegWrapperFunction = (func)dlsym(handle, "Java_com_yourpackage_androidffmpegwrapper_FfmpegJNIWrapper_ffmpegWrapper");
reenterable_ffmpegWrapperFunction(pEnv, pObj, javaArgv); //the original arguments
//Close the library
dlclose(handle);
// return
return(1);
}