准备工具
- Android开发工具AS(需要下载NDK)
- ffmpeg交叉编译后的动态库或静态库以及头文件
接入步骤
新建Native C++工程并引入头文件和动态库:
编写CMakeLists.txt文件:
cmake_minimum_required(VERSION 3.4.1)
# 引入FFmpeg的头文件
include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include)
# 方式一
# 引入FFmpeg的库文件,设置内部的方式引入,指定库的目录是 -L 指定具体的库-l
# 这种方式方便快捷
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/libs/${CMAKE_ANDROID_ARCH_ABI}")
# 方式二
#设置ffmpeg库所在路径的变量
#set(FF ${CMAKE_SOURCE_DIR}/${CMAKE_ANDROID_ARCH_ABI})
#add_library(avcodec SHARED IMPORTED)
#set_target_properties(avcodec PROPERTIES IMPORTED_LOCATION ${FF}/libavcodec.so)
#
#add_library(avformat SHARED IMPORTED)
#set_target_properties(avformat PROPERTIES IMPORTED_LOCATION ${FF}/libavformat.so)
#
#add_library(avutil SHARED IMPORTED)
#set_target_properties(avutil PROPERTIES IMPORTED_LOCATION ${FF}/libavutil.so)
#
#add_library(swscale SHARED IMPORTED)
#set_target_properties(swscale PROPERTIES IMPORTED_LOCATION ${FF}/libswscale.so)
#
#add_library(swresample SHARED IMPORTED)
#set_target_properties(swresample PROPERTIES IMPORTED_LOCATION ${FF}/libswresample.so)
#
#add_library(avfilter SHARED IMPORTED)
#set_target_properties(avfilter PROPERTIES IMPORTED_LOCATION ${FF}/libavfilter.so)
#找到包含所有的cpp文件
file(GLOB allCpp src/main/cpp/*.*)
add_library(
# 生成的库的名字
flyffmpeg-lib
# 动态库
SHARED
# 源文件
${allCpp} )
target_link_libraries( #目标库
flyffmpeg-lib
# 把ffmpeg的动态库依赖进来
avformat
avcodec
avutil
avfilter
swscale
swresample
# NDK中的log库
log )
相关注释都已经写的很清楚了,这里就不再多解析了。ffmpeg就引入进去后,下面我编写一个简答的代码调用一下ffmpeg的相关api测试下是否能正常调用。
新建一个native方法获取ffmpeg的版本号:
public native static String getFFmpegVersion();
jni相关代码:
#include <jni.h>
#include <string>
// 因为ffmpeg是纯C代码,要在cpp中使用则需要使用 extern "C"
extern "C" {
#include "libavutil/avutil.h"
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_flyer_ffmpeg_FFmpegUtils_getFFmpegVersion(JNIEnv *env, jclass clazz) {
//通过av_version_info()获取版本号
return env -> NewStringUTF(av_version_info());
}
通过TextView显示一下获取到的版本号:
遇到的问题
- 报错ffmpeg的相关库没有找到
解决方法:检查你项目的CMakeLists.txt
中的ffmpeg相关库有没有正确链接;
检查build.gradle
中有没有配置好将相关so打包进去apk的配置:
sourceSets {
main {
//将依赖库打进apk,否则可能出现找不到库
jniLibs.srcDirs = ['libs']
}
}
- 报自定义封装的so库找不到
解决方法:检查build.gradle
中是否设置了abiFilters
笔者的环境实验发现在cmake中设置abiFilters无效,依然会报so无法找到的错误,但是在ndk中设置则正常;
externalNativeBuild(){
cmake{
// 为什么在这里指定编译架构会报so库找不到的错误,而在ndk中指定则不会???
// abiFilters "armeabi-v7a" //指定编译为 armeabi-v7a
}
ndk {
abiFilters "armeabi-v7a"
}
}
最后如果你对音视频开发感兴趣可扫码关注,后续我们共同探讨,共同进步。
本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/18537.html