一、創(chuàng)建native項(xiàng)目
1.1、選擇Native C++
1.2、命名項(xiàng)目名稱
1.3、選擇C++標(biāo)準(zhǔn)
1.4、項(xiàng)目結(jié)構(gòu)
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++使用標(biāo)準(zhǔn) - 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
設(shè)置項(xiàng)目名稱 -
add_library
添加庫并設(shè)置庫的源文件
1、 Normal Libraries
add_library(<name> [STATIC | SHARED | MODULE]
[EXCLUDE_FROM_ALL]
[<source>...])
name:庫名稱
STATIC|SHARED|MODULE:庫類型(靜態(tài)、動(dòng)態(tài)、模塊)
source:源文件
2、Imported Libraries
add_library(<name> <type> IMPORTED [GLOBAL])
導(dǎo)入已經(jīng)生成的庫,通常情況搭配set_target_properties,指定庫的相關(guān)配置信息
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
用于指定目標(biāo)(target)與其所需的庫之間的鏈接關(guān)系。它被用于在構(gòu)建過程中將庫文件鏈接到可執(zhí)行文件或共享庫。
target_link_libraries(
ffmpegnative
${log-lib})
將log-lib庫鏈接到ffmpegnative中
二、配置FFmpeg頭文件和庫
2.1、配置FFmpeg頭文件
#設(shè)置頭文件路徑
include_directories(${CMAKE_SOURCE_DIR}/include)
2.2、配置ffmpeg相關(guān)的so庫
2.2.1、添加so庫
#聲明ffmpeg_lib_dir變量,設(shè)置統(tǒng)一的庫文件路徑
set(ffmpeg_lib_dir ${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})
#添加ffmpeg相關(guān)的庫
#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庫(圖像格式轉(zhuǎn)換的模塊)
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庫(輸入輸出設(shè)備庫,提供設(shè)備數(shù)據(jù)的輸入與輸出)
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相關(guān)庫
avutil
swresample
avcodec
avfilter
swscale
avformat
avdevice
#鏈接本地日志庫
${log-lib})
2.3、ffmpeg靜態(tài)庫配置
2.3.1、拷貝靜態(tài)庫到j(luò)niLibs文件夾
2.3.2、把靜態(tài)庫路徑設(shè)置到默認(rèn)的編譯變量或者庫的搜索變量中
2.3.2.1、設(shè)置CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS 是 CMake 構(gòu)建系統(tǒng)中用于設(shè)置 C++ 編譯器選項(xiàng)的變量。通過設(shè)置 CMAKE_CXX_FLAGS 變量,您可以向編譯器傳遞各種編譯選項(xiàng)和標(biāo)志。
#聲明ffmpeg路徑變量,設(shè)置統(tǒng)一的庫文件路徑
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)
#設(shè)置ffmpeg庫文件路徑
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${FFMPEG_DIR}/lib/${ANDROID_ABI}")
#設(shè)置ffmpeg的頭文件
include_directories(${FFMPEG_DIR}/include)
CmakeLists.txt
cmake_minimum_required(VERSION 3.18.1)
project("ffmpegnative")
#聲明ffmpeg路徑變量,設(shè)置統(tǒng)一的庫文件路徑
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)
#設(shè)置ffmpeg庫文件路徑
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${FFMPEG_DIR}/lib/${ANDROID_ABI}")
#設(shè)置ffmpeg的頭文件
include_directories(${FFMPEG_DIR}/include)
add_library(
ffmpegnative
SHARED
native-lib.cpp
)
target_link_libraries(
ffmpegnative
#鏈接ffmpeg相關(guān)庫
${FFMPEG_LIB}
#鏈接本地日志庫
${ANDROID_LIB})
2.3.2.2、使用LINK_DIRECTORIES,設(shè)置靜態(tài)庫
LINK_DIRECTORIES是CMake構(gòu)建系統(tǒng)中的一個(gè)命令,用于指定編譯器在鏈接階段查找?guī)煳募乃阉髀窂?/strong>。
在CMakeLists.txt文件中,可以使用LINK_DIRECTORIES命令來指定庫文件的搜索路徑
#聲明ffmpeg路徑變量,設(shè)置統(tǒng)一的庫文件路徑
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)
#設(shè)置ffmpeg庫文件搜索路徑
LINK_DIRECTORIES(${FFMPEG_DIR}/lib/${ANDROID_ABI})
#設(shè)置ffmpeg的頭文件
include_directories(${FFMPEG_DIR}/include)
CmakeLists.txt
cmake_minimum_required(VERSION 3.18.1)
project("ffmpegnative")
#聲明ffmpeg路徑變量,設(shè)置統(tǒng)一的庫文件路徑
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)
#設(shè)置ffmpeg庫文件搜索路徑
LINK_DIRECTORIES(${FFMPEG_DIR}/lib/${ANDROID_ABI})
#設(shè)置ffmpeg的頭文件
include_directories(${FFMPEG_DIR}/include)
add_library(
ffmpegnative
SHARED
native-lib.cpp
)
target_link_libraries(
ffmpegnative
#鏈接ffmpeg相關(guān)庫
${FFMPEG_LIB}
#鏈接本地日志庫
${ANDROID_LIB})
三、編譯測試
3.1、錯(cuò)誤一
- 把1.6.1修改為1.5.1
3.2、編譯arm64-v8a錯(cuò)誤
- 因?yàn)槲覀冎慌渲昧薬rmeabi-v7a,所以我們需要指定只編譯armeabi-v7a的
3.3、多個(gè)相同文件問題
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
3.4、找不到so庫文件
為了使目錄更加清晰,我在jniLibs目錄下增加了新的目錄,運(yùn)行以后,程序報(bào)出無法找到so庫文件,生成的apk文件里面也沒有把相關(guān)的so庫打包進(jìn)去
解決方案:
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jniLibs/lib']
}
}
在build.gradle的文件下配置好so庫文件所在的路徑
四、調(diào)用ffmpeg相關(guān)api
4.1、聲明native函數(shù)
public native String getFFmpegVersion();
4.2、實(shí)現(xiàn)native函數(shù)
#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);
}
文章來源:http://www.zghlxwxcb.cn/news/detail-699179.html
- 沒有正確添加依賴,指定確保C++編譯器按照C語言的約定處理函數(shù)
4.3、調(diào)用測試
文章來源地址http://www.zghlxwxcb.cn/news/detail-699179.html
到了這里,關(guān)于ffmpeg-android studio創(chuàng)建jni項(xiàng)目的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!