本文是在ffmpeg的編譯完成的基礎(chǔ)上用cmake對(duì)ffmpeg的so庫(kù)進(jìn)行調(diào)用
具體步驟
一、創(chuàng)建一個(gè)包含c++的項(xiàng)目
創(chuàng)建新項(xiàng)目的時(shí)候,記得勾選include c++ support,項(xiàng)目中會(huì)在main目錄下自動(dòng)創(chuàng)建cpp目錄并生成一個(gè)現(xiàn)成的cpp文件。
二、將生成的so庫(kù)和頭文件拷貝進(jìn)項(xiàng)目中
1、在main目錄下創(chuàng)建jnilibs目錄并創(chuàng)建對(duì)應(yīng)的abi目錄(由于我生成的ffmpeg僅僅支持armeabi和armeabi-v7a,而armeabi又不需要?jiǎng)?chuàng)建,所以此處只創(chuàng)建了armeabi-v7a目錄),將ffmpeg的so庫(kù)復(fù)制進(jìn)去。
image.png

image.png
效果如下:

image.png
三、配置CMakeLists.txt 文件(CMake構(gòu)建腳本)
具體在CMakeLists中添加的Cmake命令用法,請(qǐng)參考這篇文章
需要注意的是CMakelists的位置,CMAKE_SOURCE_DIR就代表CMakeLists所在的路徑。我的項(xiàng)目中CMakeLists的路徑是與build.gradle同級(jí)的

image.png
下面貼出我的CMakeLists
# For more information about using CMake with Android Studio, read the
cmake_minimum_required(VERSION 3.4.1)
set(lib_src_DIR ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI})
message("CURRENT_DIR:" ${CMAKE_SOURCE_DIR})
##添加一個(gè)庫(kù)
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
${CMAKE_SOURCE_DIR}/src/main/cpp/native-lib.cpp)
add_library(avcodec-57 SHARED IMPORTED)
add_library(avformat-57 SHARED IMPORTED)
add_library(avutil-55 SHARED IMPORTED)
add_library(swresample-2 SHARED IMPORTED)
add_library(swscale-4 SHARED IMPORTED)
set_target_properties(avcodec-57 PROPERTIES IMPORTED_LOCATION
${lib_src_DIR}/libavcodec-57.so)
set_target_properties(avformat-57 PROPERTIES IMPORTED_LOCATION
${lib_src_DIR}/libavformat-57.so)
set_target_properties(avutil-55 PROPERTIES IMPORTED_LOCATION
${lib_src_DIR}/libavutil-55.so)
set_target_properties(swresample-2 PROPERTIES IMPORTED_LOCATION
${lib_src_DIR}/libswresample-2.so)
set_target_properties(swscale-4 PROPERTIES IMPORTED_LOCATION
${lib_src_DIR}/libswscale-4.so)
include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include)
#找到log庫(kù)
find_library( # Sets the name of the path variable.
log-lib
log)
##給目標(biāo)庫(kù)添加依賴庫(kù)
target_link_libraries(
native-lib#目標(biāo)庫(kù)
# 依賴庫(kù),可以寫多個(gè)
${log-lib}
avcodec-57
avformat-57
avutil-55
swresample-2
swscale-4)
Androidstudio最新版好像創(chuàng)建完c++后自動(dòng)生成的CMakeLists是在cpp目錄下的,這個(gè)CMakeLists在哪都行,不過千萬要記住修改幾處調(diào)用CMakeLists路徑的地方。有以下幾處:
1、CMakeLists中用到CMAKE_SOURCE_DIR的地方

image.png
2、build.gradle中

image.png
四、編寫 C++代碼
include/libavcodec/avcodec.h是引用的so庫(kù)的頭文件,需要注意使用extern "C"包裹起來
#include <jni.h>
#include <string>
extern "C" {
#include "include/libavcodec/avcodec.h"
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_face_jfshare_nativetest_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_face_jfshare_nativetest_MainActivity_stringTest(JNIEnv *env,
jobject /* this */) {
char info[10000] = {0};
sprintf(info, "%s\n", avcodec_configuration());
return env->NewStringUTF(info);
}
五、調(diào)用本地代碼
public class MainActivity extends AppCompatActivity {
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Example of a call to a native method
TextView tv = findViewById(R.id.sample_text);
tv.setText(stringTest());
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
public native String stringTest();
}
六、運(yùn)行app

56895DA6D4025A63FAF295CED96F3C2F.jpg
注意事項(xiàng)
1:由于我生成的ffmpeg僅僅支持armeabi和armeabi-v7a所以在build.gradle中需要注意只能匹配armeabi-v7a(高版本ndk不允許匹配armeabi)
ndk{
abiFilters "armeabi-v7a"
}
參考鏈接:
1、https://www.cnblogs.com/fnlingnzb-learner/p/7593488.html
2、http://www.itdecent.cn/p/a1fe55d5683b