3.2 本地方法并生成头文件
java代码如下:
public class NativeAPI { public static native String stringFromJNI(); public static native String urlprotocolinfo(); public static native String avformatinfo(); public static native String avcodecinfo(); public static native String avfilterinfo(); }
生成头文件,如果不知道怎么快速生成,请参考AndroidStudio JNI 快速生成头文件。
3.3 编写本地方法的实现
首先要引入FFmpeg库文件,拷贝so库到libs文件夹:
image.png
拷贝FFmpeg的头文件到指定目录,这个目录并不确定,只要在CMakeList.txt中引入即可:
image.png
修改build.gradle文件,在defaultconfig中添加指定平台,还记得编译FFmpeg时的arch=armv7-a
参数吧,一定要对应,否则编译可以通过,但是运行时会报错。
//指定平台,与编译FFmpeg时的arch参数对应 ndk{ abiFilters 'armeabi-v7a' } //指定SO库路径
3.4 CMakeList.txt
# For more information about using CMake with Android Studio, read the # documentation: https://d.android.com/studio/projects/add-native-code.html #lib库工程名,并非so生成的so库名称,可以不写 project(TestFFmpeg) # Sets the minimum version of CMake required to build the native library. cmake_minimum_required(VERSION 3.4.1) #包含指定目录的头文件 include_directories(include/) #添加库文件 参数:生成的库名称 动态库(即so库) 源文件 add_library(native-lib SHARED native-lib.cpp) #创建导入的库目标,FFmpeg7个SO库 add_library(avutil-55 SHARED IMPORTED) add_library(swresample-2 SHARED IMPORTED) add_library(avcodec-57 SHARED IMPORTED) add_library(avfilter-6 SHARED IMPORTED) add_library(swscale-4 SHARED IMPORTED) add_library(avdevice-57 SHARED IMPORTED) add_library(avformat-57 SHARED IMPORTED) #设置变量,CMAKE_SOURCE_DIR是CMakeList.txt的路径 set(LIB_DIR ${CMAKE_SOURCE_DIR}/../../../libs/${ANDROID_ABI}) #message(SEND_ERROR "jni libs dir=${LIB_DIR}") #设置目标属性,例如avutil-55的IMPORTED_LOCATION属性值是${LIB_DIR}/libavutil-55.so set_target_properties(avutil-55 PROPERTIES IMPORTED_LOCATION ${LIB_DIR}/libavutil-55.so) set_target_properties(swresample-2 PROPERTIES IMPORTED_LOCATION ${LIB_DIR}/libswresample-2.so) set_target_properties(avcodec-57 PROPERTIES IMPORTED_LOCATION ${LIB_DIR}/libavcodec-57.so) set_target_properties(avfilter-6 PROPERTIES IMPORTED_LOCATION ${LIB_DIR}/libavfilter-6.so) set_target_properties(swscale-4 PROPERTIES IMPORTED_LOCATION ${LIB_DIR}/libswscale-4.so) set_target_properties(avdevice-57 PROPERTIES IMPORTED_LOCATION ${LIB_DIR}/libavdevice-57.so ) set_target_properties(avformat-57 PROPERTIES IMPORTED_LOCATION ${LIB_DIR}/libavformat-57.so) #在指定目录下搜索一个库, 保存在变量中 find_library( # 变量名 log-lib #搜索log库 log) #目标文件与库文件进行链接 target_link_libraries( # Specifies the target library. native-lib # Links the target library to the log library # included in the NDK. avutil-55 swresample-2 avcodec-57 avfilter-6 swscale-4 avdevice-57 avformat-57 ${log-lib})
native-lib.cpp
没有写完整,最后有Demo地址
extern "C" { //因为FFmpeg是C库,所以要在extern "C"里面 #include "include/com_flyscale_testforffmpeg_NativeAPI.h" #include "include/libavformat/avformat.h" #include "include/libavutil/avutil.h" #include "include/libavfilter/avfilter.h" #include "include/libavcodec/avcodec.h" JNIEXPORT jstring JNICALL Java_com_flyscale_testforffmpeg_NativeAPI_urlprotocolinfo (JNIEnv *env, jclass clazz) { char info[40000] = {0}; av_register_all(); struct URLProtocol *pup = NULL; struct URLProtocol **p_temp = &pup; avio_enum_protocols((void **) p_temp, 0); while ((*p_temp) != NULL) { sprintf(info, "%sInput: %s\n", info, avio_enum_protocols((void **) p_temp, 0)); } pup = NULL; avio_enum_protocols((void **) p_temp, 1); while ((*p_temp) != NULL) { sprintf(info, "%sInput: %s\n", info, avio_enum_protocols((void **) p_temp, 1)); } return env->NewStringUTF(info); } ...
运行即可。
参考:
android开发-Windows环境下编译FFMPEG源码
AndroidStudio中使用FFMPEG入门
Android Studio 中的 CMake message 输出位置在哪里