在Android项目中使用ffmpeg
- 新建一个
Module
-
选择
Android Native Library -
在
src->main目录下新建jniLibs -
在
jniLibs目录下新建arm64-v8aarmeabi-v7a目录,将编译生成的lib目录下的动态库分别拷贝过来
- 将编译生成的
include拷贝到cpp文件下
- 修改CMakeLists.txt文件
cmake_minimum_required(VERSION 3.10.2)
project("ffmpeg")
# 包含头文件
include_directories(src/main/cpp/include)
add_library(
native-lib
SHARED
src/main/cpp/ffmpeg.cpp)
add_library(avcodec SHARED IMPORTED)
set_target_properties(avcodec
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavcodec.so)
add_library(avdevice SHARED IMPORTED)
set_target_properties(avdevice
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavdevice.so)
add_library(avfilter SHARED IMPORTED)
set_target_properties(avfilter
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavfilter.so)
add_library(avformat SHARED IMPORTED)
set_target_properties(avformat
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavformat.so)
add_library(avutil SHARED IMPORTED)
set_target_properties(avutil
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavutil.so)
add_library(swresample SHARED IMPORTED)
set_target_properties(swresample
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libswresample.so)
add_library(swscale SHARED IMPORTED)
set_target_properties(swscale
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libswscale.so)
find_library(
log-lib
log)
target_link_libraries(
native-lib
${log-lib}
avcodec
avdevice
avfilter
avformat
avutil
swresample
swscale)
- 在build.gradle中添加支持的平台
ndk {
abiFilters "arm64-v8a", "armeabi-v7a"
}
- 如果提示有多个动态库,添加如下代码
packagingOptions {
pickFirst 'lib/arm64-v8a/libswscale.so'
pickFirst 'lib/arm64-v8a/libavcodec.so'
pickFirst 'lib/arm64-v8a/libavutil.so'
pickFirst 'lib/arm64-v8a/libavformat.so'
pickFirst 'lib/arm64-v8a/libavfilter.so'
pickFirst 'lib/arm64-v8a/libswresample.so'
pickFirst 'lib/arm64-v8a/libavdevice.so'
}
- 在java中加载动态库
static {
System.loadLibrary("native-lib");
System.loadLibrary("avutil");
System.loadLibrary("swresample");
System.loadLibrary("avcodec");
System.loadLibrary("avformat");
System.loadLibrary("swscale");
System.loadLibrary("avfilter");
System.loadLibrary("avdevice");
}
- 在cpp文件中获得配置信息,能成功显示则ffmpeg调用成功
#include <jni.h>
#include <string>
#include <android/log.h>
#define LOGI(FORMAT,...) __android_log_print(ANDROID_LOG_INFO,"cpp",FORMAT,##__VA_ARGS__);
#define LOGE(FORMAT,...) __android_log_print(ANDROID_LOG_ERROR,"cpp",FORMAT,##__VA_ARGS__);
extern "C" {
#include <libavcodec/avcodec.h>
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_tdy_ffmpeg_NativeLib_stringFromJNI(
JNIEnv* env,
jclass clazz) {
std::string config = avcodec_configuration();
LOGE("configuration %s\n",config.c_str());
return env->NewStringUTF(config.c_str());
}
注意
#include <libavcodec/avcodec.h>,要用extern "C" {}括起来,因为ffmpeg是纯c写的,不括起来会报错无法使用