一、创建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})
-
cmake_minimum_required
cmake最低版本要求 -
project
设置项目名称 -
add_library
添加库并设置库的源文件
1、 Normal Libraries
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
查找本地库,一般位于NDK中
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})
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);
}
文章来源:https://www.toymoban.com/news/detail-699179.html
- 没有正确添加依赖,指定确保C++编译器按照C语言的约定处理函数
4.3、调用测试
文章来源地址https://www.toymoban.com/news/detail-699179.html
到了这里,关于ffmpeg-android studio创建jni项目的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!