怎麼在Android專案中匯入ffmpeg庫?

故鄉的櫻花開了發表於2023-12-12

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)執行程式

 

相關文章