上一篇文章介紹了如何在Mac平臺下編譯FFMPEG皮获,這篇主要介紹如何將編譯后的so文件導入Android項目中焙蚓,
-
項目文件目錄結構
WX20190619-162908.pngsrc/main/cpp/include包下的文件可以從FFMPEG編譯后的任意CPU架構目錄下直接拷貝到cpp目錄下即可
-
src/main/jniLibs/包下的文件可以從FFMPEG編譯后的對應的CPU架構Lib包下拷貝,只需要拷貝以帶版本號的so文件即可洒宝,如:libavcodec-57.so
WX20190619-163538@2x.png
-
配置項目的build.gradle文件
android { ..... externalNativeBuild { cmake { path "CMakeLists.txt" } } sourceSets{ main{ jniLibs.srcDirs = ["src/main/jniLibs"] } } }
-
配置CMakeLists.txt文件
# Cmake版本號 cmake_minimum_required(VERSION 3.4.1) #項目自動生成的代碼 add_library( native-lib SHARED src/main/cpp/native-lib.cpp) #復用NDK中一些基礎的庫购公,如輸出log等 find_library( log-lib log) #導入FFMPEG動態(tài)庫: #1.導入FFMEPG頭文件夾路徑 include_directories(src/main/cpp/include) #2. 添加動態(tài)庫: 庫名 SHARED IMPORTED add_library(avcodec-57 SHARED IMPORTED) #3. 設置動態(tài)庫路徑:${CMAKE_SOURCE_DIR}表示CmakeList文件目錄 ${ANDROID_ABI}表示系統CPU架構 set_target_properties(avcodec-57 PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavcodec-57.so) #其他so文件按照第2、3步重復操作即可雁歌,只需要替換對應的so庫名稱即可 add_library( avdevice-57 SHARED IMPORTED) set_target_properties( avdevice-57 PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavdevice-57.so) add_library( avfilter-6 SHARED IMPORTED) set_target_properties( avfilter-6 PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavfilter-6.so) add_library( avformat-57 SHARED IMPORTED) set_target_properties( avformat-57 PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavformat-57.so) add_library( avutil-55 SHARED IMPORTED) set_target_properties( avutil-55 PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavutil-55.so) add_library( postproc-54 SHARED IMPORTED) set_target_properties( postproc-54 PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libpostproc-54.so) add_library( swresample-2 SHARED IMPORTED) set_target_properties( swresample-2 PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libswresample-2.so) add_library( swscale-4 SHARED IMPORTED) set_target_properties( swscale-4 PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libswscale-4.so) #4. 鏈接動態(tài)庫 target_link_libraries( native-lib ${log-lib} # FFMPEG相關的類庫 avcodec-57 avdevice-57 avfilter-6 avformat-57 avutil-55 postproc-54 swresample-2 swscale-4)
-
編寫C++測試代碼:
#include <jni.h> #include <string> #include <android/log.h> //由于調用時是用C語言寫的宏浩,所以也要用extern聲明是C,否則編譯時會報錯 extern "C"{ #include <libavformat/avformat.h> } //定義打印Log方法 #define LOGI(FORMAT,...) __android_log_print(ANDROID_LOG_INFO,"MyPlayer",FORMAT,##__VA_ARGS__); extern "C" JNIEXPORT jstring JNICALL Java_cn_rongrtc_mylibrary_Demo_stringFromJNI( JNIEnv *env, jobject /* this */) { //注冊所有的解碼器 av_register_all(); //獲取所有的解碼器 AVCodec *c_temp = av_codec_next(NULL); //遍歷解碼器并打印解碼器名稱 while (c_temp != NULL) { switch (c_temp->type) { case AVMEDIA_TYPE_VIDEO: LOGI("[Video]:%s", c_temp->name); break; case AVMEDIA_TYPE_AUDIO: LOGI("[Audio]:%s", c_temp->name); break; default: LOGI("[Other]:%s", c_temp->name); break; } c_temp = c_temp->next; } std::string hello = "Hello from Demo C++"; return env->NewStringUTF(hello.c_str()); }
-
編寫Java層代碼
public class Demo { // Used to load the 'native-lib' library on application startup. static { System.loadLibrary("native-lib"); System.loadLibrary("avcodec-57"); System.loadLibrary("avdevice-57"); System.loadLibrary("avfilter-6"); System.loadLibrary("avformat-57"); System.loadLibrary("avutil-55"); System.loadLibrary("postproc-54"); System.loadLibrary("swresample-2"); System.loadLibrary("swscale-4"); } /** * A native method that is implemented by the 'native-lib' native library, * which is packaged with this application. */ public static native String stringFromJNI(); }
遇到的問題
-
同步代碼或編譯時如果有類似的報錯:
Error while executing process /Users/www/Library/Android/sdk/cmake/3.10.2.4988404/bin/cmake with arguments {--build /Users/www/codeSamples/ffmpeg/MusicPlayer/mylibrary/.externalNativeBuild/cmake/debug/arm64-v8a --target native-lib}
ninja: error: '../../../../src/main/jniLibs/arm64-v8a/libavcodec-57.so', needed by '../../../../build/intermediates/cmake/debug/obj/arm64-v8a/libnative-lib.so', missing and no known rule to make it
-
如果出現類似報錯則有可能是你的so庫不支持你手機CPU架構靠瞎,你需要編譯一份對應的CPU架構so庫并拷貝到jniLibs目錄下即可比庄。具體如何編譯可以參考上一篇文章Mac平臺下編譯FFMPEG