ffmpeg-android studio创建jni项目

一、创建native项目

1.1、选择Native C++

在这里插入图片描述

1.2、命名项目名称

在这里插入图片描述

1.3、选择C++标准

在这里插入图片描述

1.4、项目结构

在这里插入图片描述

1.5、app的build.gradle

plugins {
    id 'com.android.application'
}

android {
    compileSdk 32

    defaultConfig {
        applicationId "com.anniljing.ffmpegnative"
        minSdk 25
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags '-std=c++11'
            }
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    externalNativeBuild {
        cmake {
            path file('src/main/cpp/CMakeLists.txt')
            version '3.18.1'
        }
    }
    buildFeatures {
        viewBinding true
    }
}

dependencies {

    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.9.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}
  • android -> defaultConfig ->externalNativeBuild -> cmake
    配置c++使用标准
  • android -> externalNativeBuild -> cmake
    1 、配置cmake文件路径
    2、配置cmake的版本

1.6、CMakeLists.txt

cmake_minimum_required(VERSION 3.18.1)

project("ffmpegnative")


add_library( # Sets the name of the library.
        ffmpegnative

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        native-lib.cpp)

find_library( # Sets the name of the path variable.
        log-lib

        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log)


target_link_libraries( # Specifies the target library.
        ffmpegnative

        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})
add_library(<name> [STATIC | SHARED | MODULE]
            [EXCLUDE_FROM_ALL]
            [<source>...])

name:库名称
STATIC|SHARED|MODULE:库类型(静态、动态、模块)
source:源文件

2、Imported Libraries

add_library(<name> <type> IMPORTED [GLOBAL])

导入已经生成的库,通常情况搭配set_target_properties,指定库的相关配置信息

set_target_properties(target1 target2 ...
                      PROPERTIES prop1 value1
                      prop2 value2 ...)
find_library( # Sets the name of the path variable.
        log-lib

        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log)

在这里插入图片描述

  • target_link_libraries
    用于指定目标(target)与其所需的库之间的链接关系。它被用于在构建过程中将库文件链接到可执行文件或共享库。
target_link_libraries(
        ffmpegnative
        ${log-lib})

将log-lib库链接到ffmpegnative中

二、配置FFmpeg头文件和库

2.1、配置FFmpeg头文件

#设置头文件路径
include_directories(${CMAKE_SOURCE_DIR}/include)

在这里插入图片描述

2.2、配置ffmpeg相关的so库

2.2.1、添加so库

#声明ffmpeg_lib_dir变量,设置统一的库文件路径
set(ffmpeg_lib_dir ${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})
#添加ffmpeg相关的库
#avcodec(音视频编解码核心库)
add_library( avcodec
        SHARED
        IMPORTED )
set_target_properties( avcodec
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libavcodec.so )

#avfilter(音视频滤镜库 如视频加水印、音频变声)
add_library( avfilter
        SHARED
        IMPORTED)
set_target_properties( avfilter
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libavfilter.so )

#swscale(图像格式转换的模块)
add_library( swscale
        SHARED
        IMPORTED)
set_target_properties( swscale
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libswscale.so )

#avformat(音视频容器格式的封装和解析)
add_library( avformat
        SHARED
        IMPORTED)
set_target_properties( avformat
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libavformat.so )

#avdevice(输入输出设备库,提供设备数据的输入与输出)
add_library( avdevice
        SHARED
        IMPORTED)
set_target_properties( avdevice
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libavdevice.so )

#avutil(核心工具库)
add_library( avutil
        SHARED
        IMPORTED )
set_target_properties( avutil
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libavutil.so )

#swresample(音频重采样)
add_library( swresample
        SHARED
        IMPORTED )
set_target_properties( swresample
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libswresample.so )

在这里插入图片描述

2.2.2、链接ffmpeg库

target_link_libraries(
        ffmpegnative
        #链接ffmpeg相关库
        avutil
        swresample
        avcodec
        avfilter
        swscale
        avformat
        avdevice
        #链接本地日志库
        ${log-lib})

链接ffmpeg库

2.3、ffmpeg静态库配置

2.3.1、拷贝静态库到jniLibs文件夹

在这里插入图片描述

2.3.2、把静态库路径设置到默认的编译变量或者库的搜索变量中

2.3.2.1、设置CMAKE_CXX_FLAGS

CMAKE_CXX_FLAGS 是 CMake 构建系统中用于设置 C++ 编译器选项的变量。通过设置 CMAKE_CXX_FLAGS 变量,您可以向编译器传递各种编译选项和标志。

#声明ffmpeg路径变量,设置统一的库文件路径
set(FFMPEG_DIR ${CMAKE_SOURCE_DIR}/../jniLibs/ffmpeg)
#声明ffmpeg包含所有库变量
set(FFMPEG_LIB avformat avcodec avdevice avfilter avutil swresample swscale)
set(ANDROID_LIB z -landroid log)

#设置ffmpeg库文件路径
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${FFMPEG_DIR}/lib/${ANDROID_ABI}")
#设置ffmpeg的头文件
include_directories(${FFMPEG_DIR}/include)

CmakeLists.txt

cmake_minimum_required(VERSION 3.18.1)

project("ffmpegnative")

#声明ffmpeg路径变量,设置统一的库文件路径
set(FFMPEG_DIR ${CMAKE_SOURCE_DIR}/../jniLibs/ffmpeg)
#声明ffmpeg包含所有库变量
set(FFMPEG_LIB avformat avcodec avdevice avfilter avutil swresample swscale)
set(ANDROID_LIB z -landroid log)


#设置ffmpeg库文件路径
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${FFMPEG_DIR}/lib/${ANDROID_ABI}")
#设置ffmpeg的头文件
include_directories(${FFMPEG_DIR}/include)


add_library(
        ffmpegnative
        SHARED
        native-lib.cpp

)


target_link_libraries(
        ffmpegnative
        #链接ffmpeg相关库
        ${FFMPEG_LIB}
        #链接本地日志库
        ${ANDROID_LIB})
2.3.2.2、使用LINK_DIRECTORIES,设置静态库

LINK_DIRECTORIES是CMake构建系统中的一个命令,用于指定编译器在链接阶段查找库文件的搜索路径

在CMakeLists.txt文件中,可以使用LINK_DIRECTORIES命令来指定库文件的搜索路径

#声明ffmpeg路径变量,设置统一的库文件路径
set(FFMPEG_DIR ${CMAKE_SOURCE_DIR}/../jniLibs/ffmpeg)
#声明ffmpeg包含所有库变量
set(FFMPEG_LIB avformat avcodec avdevice avfilter avutil swresample swscale)
set(ANDROID_LIB z -landroid log)


#设置ffmpeg库文件搜索路径
LINK_DIRECTORIES(${FFMPEG_DIR}/lib/${ANDROID_ABI})
#设置ffmpeg的头文件
include_directories(${FFMPEG_DIR}/include)

CmakeLists.txt

cmake_minimum_required(VERSION 3.18.1)

project("ffmpegnative")

#声明ffmpeg路径变量,设置统一的库文件路径
set(FFMPEG_DIR ${CMAKE_SOURCE_DIR}/../jniLibs/ffmpeg)
#声明ffmpeg包含所有库变量
set(FFMPEG_LIB avformat avcodec avdevice avfilter avutil swresample swscale)
set(ANDROID_LIB z -landroid log)


#设置ffmpeg库文件搜索路径
LINK_DIRECTORIES(${FFMPEG_DIR}/lib/${ANDROID_ABI})
#设置ffmpeg的头文件
include_directories(${FFMPEG_DIR}/include)


add_library(
        ffmpegnative
        SHARED
        native-lib.cpp

)


target_link_libraries(
        ffmpegnative
        #链接ffmpeg相关库
        ${FFMPEG_LIB}
        #链接本地日志库
        ${ANDROID_LIB})

三、编译测试

3.1、错误一

在这里插入图片描述

  • 把1.6.1修改为1.5.1

在这里插入图片描述

3.2、编译arm64-v8a错误

在这里插入图片描述

  • 因为我们只配置了armeabi-v7a,所以我们需要指定只编译armeabi-v7a的
    在这里插入图片描述

3.3、多个相同文件问题

在这里插入图片描述

 sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }

在这里插入图片描述

3.4、找不到so库文件

为了使目录更加清晰,我在jniLibs目录下增加了新的目录,运行以后,程序报出无法找到so库文件,生成的apk文件里面也没有把相关的so库打包进去
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
解决方案:

 sourceSets {
        main {
            jniLibs.srcDirs = ['src/main/jniLibs/lib']
        }
    }

在build.gradle的文件下配置好so库文件所在的路径
在这里插入图片描述

四、调用ffmpeg相关api

4.1、声明native函数

public native String getFFmpegVersion();

在这里插入图片描述

4.2、实现native函数

#include <libavformat/avformat.h>

extern "C"
JNIEXPORT jstring JNICALL
Java_com_anniljing_ffmpegnative_MainActivity_getFFmpegVersion(JNIEnv *env, jobject thiz) {
    const char* version = av_version_info();

    return env->NewStringUTF(version);
}

在这里插入图片描述
在这里插入图片描述

  • 没有正确添加依赖,指定确保C++编译器按照C语言的约定处理函数
    在这里插入图片描述

4.3、调用测试

在这里插入图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 Android Studio 中使用 FFmpeg 的 so 库,可以按照以下步骤进行操作: 1. 将 FFmpeg 的 so 库添加到项目中: 将 FFmpeg 的 so 库文件拷贝到项目的 `src/main/jniLibs` 目录下,其中 `src/main` 是项目的主目录,`jniLibs` 是自己创建的目录,用于存放 JNI 动态库文件。 2. 在 build.gradle 中配置 ndk 和 sourceSets: 在 `build.gradle` 文件中添加以下配置: ``` android { ... defaultConfig { ... ndk { // 指定支持的 CPU 架构 abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' } } sourceSets { main { jniLibs.srcDirs = ['src/main/jniLibs'] } } } ``` 3. 创建 JNI 接口: 在项目的 `src/main/java` 目录下创建一个 Java 类,用于实现 JNI 接口。例如,可以创建一个名为 `FFmpegJNI` 的类,其中包含以下代码: ``` public class FFmpegJNI { static { System.loadLibrary("ffmpeg"); } public static native String avcodecConfiguration(); } ``` 其中,`System.loadLibrary("ffmpeg")` 用于加载 FFmpeg 的 so 库,`avcodecConfiguration()` 方法是 JNI 接口中的一个方法,用于获取 FFmpeg 的配置信息。 4. 生成 JNI 头文件: 在终端中进入项目的 `src/main/java` 目录下,执行以下命令: ``` javac FFmpegJNI.java javah -jni FFmpegJNI ``` 这些命令将生成一个名为 `FFmpegJNI.h` 的文件,其中包含 JNI 接口的声明。 5. 编写 JNI 实现: 在项目的 `src/main/jni` 目录下创建一个名为 `FFmpegJNI.cpp` 的文件,用于实现 JNI 接口。例如,可以创建以下代码: ``` #include <jni.h> #include <string> #include "FFmpegJNI.h" #include "libavcodec/avcodec.h" extern "C" JNIEXPORT jstring JNICALL Java_com_example_ffmpegtest_FFmpegJNI_avcodecConfiguration(JNIEnv *env, jclass clazz) { std::string result; result += "AVCodec configuration: "; result += avcodec_configuration(); return env->NewStringUTF(result.c_str()); } ``` 其中,`avcodec_configuration()` 方法是 FFmpeg 库中的一个方法,用于获取编解码器的配置信息。 6. 编译项目: 在终端中进入项目的根目录,执行以下命令: ``` ./gradlew assembleDebug ``` 这个命令将编译项目,并在 `build/outputs/apk` 目录下生成一个名为 `app-debug.apk` 的文件。 7. 运行项目: 将生成的 apk 文件安装到 Android 设备上,并运行项目。在项目中调用 `FFmpegJNI.avcodecConfiguration()` 方法,即可获取 FFmpeg 的编解码器配置信息。 注意:在 Android 6.0 及以上的版本中,需要动态获取权限才能使用 JNI 动态库文件。可以使用 ActivityCompat.requestPermissions() 方法或者在 AndroidManifest.xml 文件中声明权限。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值