怎么在Android项目中导入ffmpeg库?

发布时间 2023-12-12 23:18:23作者: 故乡的樱花开了

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)运行程序