在本地解压上一步得到的 ffmpeg.zip,将 include 和 lib 文件夹内的文件拷贝到 Android Studio 的项目中,具体步骤如下:
-
将 include 文件夹拷贝到 /src/main/cpp 目录下
-
将 lib 文件夹内的 6 个静态库(.a 结尾)文件拷贝到 /src/main/cpp/armeabi-v7a 目录下(因为我们后续要在 CPU 架构为 armeabi-v7a 的真机上使用这些静态库)
-
配置 CMakeLists 文件:
# 1、引入头文件 include_directories(${CMAKE_SOURCE_DIR}/include) # 2、引入库文件 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/${CMAKE_ANDROID_ARCH_ABI}") find_library( log-lib log) # 3、链接 FFmpeg 的静态库到目标库,注意顺序,比如 avformat 要在 # avcodec 的前面 target_link_libraries( ffmpeg ${log-lib} avformat avcodec avfilter avutil swresample swscale)
配置 target_link_libraries 时要注意 6 个静态库的顺序,因为 avcodec 是依赖 avformat 的,被依赖的库要写在前面。如果想排除掉顺序影响,可以写成下面这样:
target_link_libraries( ffmpeg ${log-lib} -Wl,--start-group avformat avcodec avfilter avutil swresample swscale -Wl,--end-group)
-
配置 build.gradle 添加 CPU 架构过滤:
android { defaultConfig { externalNativeBuild { cmake { abiFilters 'armeabi-v7a' } } ndk { abiFilters 'armeabi-v7a' } } }
-
最后调用 avutil 库中的函数,输出 FFmpeg 的版本号,测试配置是否成功:
// 因为 FFmpeg 是用纯 C 写的,所以要用 C 的方式编译 extern "C" { #include <libavutil/avutil.h> } extern "C" JNIEXPORT jstring JNICALL Java_com_linux_ffmpeg_NativeLib_stringFromJNI( JNIEnv *env, jobject /* this */) { std::string hello = "FFmpeg 版本:"; hello.append(av_version_info()); return env->NewStringUTF(hello.c_str()); }
调用 JNI 函数,我写在了 Android 单元测试中:
@RunWith(AndroidJUnit4::class) class ExampleInstrumentedTest { @Test fun test() { // Logcat 输出 test: FFmpeg 版本:4.0.6 Log.d("Test", "test: ${NativeLib().stringFromJNI()}") } }