1.前言
在這裡我以匯入靜態庫(.a)為例進行分析,動態庫(.so)是類似的。在匯入前,各位要先編譯好ffmpeg庫,需要注意的是在編譯的時候要開啟交叉編譯,目標平臺為Android,其他平臺的庫(windows,linux)在Android平臺使用不了,我這裡編譯的是armeabi-v7a架構的庫。
2.步驟
(1)新建一個native c++專案,然後在main目錄下面新建一個jniLibs目錄,將編譯好的庫放入這個目錄下,這裡貼出我的:
由於我開啟了對x264編解碼的支援,所以把libx264庫也匯入了。
(2)修改app下的build.gradle檔案,配置一下支援哪些ABI(應用程式二進位制介面),也就是支援的CPU架構型別。
defaultConfig { applicationId "cn.siat.importedffmpeg" minSdk 24 targetSdk 33 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" ndk{ abiFilters "armeabi-v7a" } }
(3)在cpp目錄下新建一個include資料夾,用於存放ffmpeg的標頭檔案。
(4)修改CMakeLists.txt檔案,匯入ffmpeg標頭檔案,並連結jniLibs下的庫檔案,程式碼如下:
# For more information about using CMake with Android Studio, read the # documentation: https://d.android.com/studio/projects/add-native-code.html. # For more examples on how to use CMake, see https://github.com/android/ndk-samples. # Sets the minimum CMake version required for this project. cmake_minimum_required(VERSION 3.22.1) # Declares the project name. The project name can be accessed via ${ PROJECT_NAME}, # Since this is the top level CMakeLists.txt, the project name is also accessible # with ${CMAKE_PROJECT_NAME} (both CMake variables are in-sync within the top level # build script scope). project("importedffmpeg") # Creates and names a library, sets it as either STATIC # or SHARED, and provides the relative paths to its source code. # You can define multiple libraries, and CMake builds them for you. # Gradle automatically packages shared libraries with your APK. # # In this top level CMakeLists.txt, ${CMAKE_PROJECT_NAME} is used to define # the target library name; in the sub-module's CMakeLists.txt, ${PROJECT_NAME} # is preferred for the same purpose. # # In order to load a library into your app from Java/Kotlin, you must call # System.loadLibrary() and pass the name of the library defined here; # for GameActivity/NativeActivity derived applications, the same library name must be # used in the AndroidManifest.xml file. include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) add_library(${CMAKE_PROJECT_NAME} SHARED # 將自己寫的cpp原始檔編譯成動態庫 native-lib.cpp)
#新增已有的靜態庫 add_library(avcodec STATIC IMPORTED)
#告知cmake靜態庫的路徑 set_target_properties(avcodec PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/armeabi-v7a/libavcodec.a) add_library(avdevice STATIC IMPORTED) set_target_properties(avdevice PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/armeabi-v7a/libavdevice.a) add_library(avfilter STATIC IMPORTED) set_target_properties(avfilter PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/armeabi-v7a/libavfilter.a) add_library(avformat STATIC IMPORTED) set_target_properties(avformat PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/armeabi-v7a/libavformat.a) add_library(avutil STATIC IMPORTED) set_target_properties(avutil PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/armeabi-v7a/libavutil.a) add_library(postproc STATIC IMPORTED) set_target_properties(postproc PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/armeabi-v7a/libpostproc.a) add_library(swresample STATIC IMPORTED) set_target_properties(swresample PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/armeabi-v7a/libswresample.a) add_library(swscale STATIC IMPORTED) set_target_properties(swscale PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/armeabi-v7a/libswscale.a) add_library(x264 STATIC IMPORTED) set_target_properties(x264 PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/armeabi-v7a/libx264.a) target_link_libraries(${CMAKE_PROJECT_NAME} # List libraries link to the target library android log avcodec avformat avdevice avfilter avutil postproc swresample swscale x264 z)
(5)修改native-lib.cpp檔案,返回ffmpeg的版本號,並進行顯示。
#include <jni.h> #include <string> extern "C"{ #include<libavcodec/avcodec.h> } extern "C" JNIEXPORT jstring JNICALL Java_cn_siat_importedffmpeg_MainActivity_stringFromJNI( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++"; return env->NewStringUTF(av_version_info()); }
(6)執行程式