先看效果图
![](https://img.haomeiwen.com/i3512130/c7b987994d1d99a4.png)
我用的是FFmpeg4.02的版本,目前编译出arm-v7a 和x86CPU架构的so文件,如果需要可以编译出全部平台,不过目前移动端的已经足够了。需要用到的有头文件和对应架构的so文件。
首先得先弄懂CMake文件的使用,如果不是理解的话,可以去官网查看用法(地址:https://developer.android.com/studio/projects/add-native-code)
CMake文件具体的描述
指定cmake的版本
cmake_minimum_required(VERSION 3.4.1)
可以把生成的so文件指定到某个目录下
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI})
生成so文件(注意:一个CMake文件只能生成一个so文件,如果想生成多个so文件,后期会写出来怎么做=。=!),这里最好是跟对接的c文件的名称一样,需要指定需要哪些需要参与的cpp文件(如果你想增加附加c文件的话,需要继续增加引用就行);SHARED表示生成的库的动态链接
add_library( # Sets the name of the library.
zplay-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
${CMAKE_SOURCE_DIR}/src/main/cpp/zplay-lib.cpp)
把对应的so文件引入进来,set_target_properties:是设置对应的路径
# 编解码
add_library(libavcodec
SHARED
IMPORTED)
set_target_properties(libavcodec PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavcodec.so)
# 和多媒体设备交互的类库
add_library(libavdevice
SHARED
IMPORTED)
set_target_properties(libavdevice PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavdevice.so)
# 图像的pixel format处理
add_library(libavfilter
SHARED
IMPORTED)
set_target_properties(libavfilter PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavfilter.so)
# 格式
add_library(libavformat
SHARED
IMPORTED)
set_target_properties(libavformat PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavformat.so)
# 工具函数
add_library(libavutil
SHARED
IMPORTED)
set_target_properties(libavutil PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavutil.so)
# 音频重采样,采样格式转换和混合库
add_library(libswresample
SHARED
IMPORTED)
set_target_properties(libswresample PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libswresample.so)
# 缩放处理
add_library(libswscale
SHARED
IMPORTED)
set_target_properties(libswscale PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libswscale.so)
再把头文件的路径也引进来
include_directories(
${CMAKE_SOURCE_DIR}/src/main/cpp/include/${ANDROID_ABI}
)
最后再把这些资源全部关联起来
target_link_libraries( # Specifies the target library.
zplay-lib
# Links the target library to the log library
# included in the NDK.
${log-lib}
libavcodec
libavdevice
libavfilter
libavformat
libavutil
libswresample
libswscale)
这是CMake文件全部的代码
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI})
# Specifies a library name, specifies whether the library is STATIC or
# SHARED, and provides relative paths to the source code. You can
# define multiple libraries by adding multiple add.library() commands,
# and CMake builds them for you. When you build your app, Gradle
# automatically packages shared libraries with your APK.
add_library( # Sets the name of the library.
zplay-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
${CMAKE_SOURCE_DIR}/src/main/cpp/zplay-lib.cpp
${CMAKE_SOURCE_DIR}/src/main/cpp/pcm/ZPcm2wav.cpp)
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
zplay-lib
# Links the target library to the log library
# included in the NDK.
${log-lib}
libavcodec
libavdevice
libavfilter
libavformat
libavutil
libswresample
libswscale)
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
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)
include_directories(
${CMAKE_SOURCE_DIR}/src/main/cpp/include/${ANDROID_ABI}
)
# 编解码
add_library(libavcodec
SHARED
IMPORTED)
set_target_properties(libavcodec PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavcodec.so)
# 和多媒体设备交互的类库
add_library(libavdevice
SHARED
IMPORTED)
set_target_properties(libavdevice PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavdevice.so)
# 图像的pixel format处理
add_library(libavfilter
SHARED
IMPORTED)
set_target_properties(libavfilter PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavfilter.so)
# 格式
add_library(libavformat
SHARED
IMPORTED)
set_target_properties(libavformat PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavformat.so)
# 工具函数
add_library(libavutil
SHARED
IMPORTED)
set_target_properties(libavutil PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavutil.so)
# 音频重采样,采样格式转换和混合库
add_library(libswresample
SHARED
IMPORTED)
set_target_properties(libswresample PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libswresample.so)
# 缩放处理
add_library(libswscale
SHARED
IMPORTED)
set_target_properties(libswscale PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libswscale.so)
再看下build.gradle文件的相关配置
如果你是在非app module里面的就需要增加
defaultConfig {
ndk {
abiFilters 'armeabi-v7a','x86'
}
}
packagingOptions {
pickFirst 'lib/armeabi-v7a/libzplay-lib.so'
pickFirst 'lib/x86/libzplay-lib.so'
}
最后显示FFmpeg的配置信息作为编译成功的验证
JNIEXPORT jstring
JNICALL
Java_com_zasko_ffmpeg_RenderManager_getConfig(JNIEnv *env, jclass type) {
char info[10000] = {0};
sprintf(info, "%s\n", avcodec_configuration());
return env->NewStringUTF(info);
}
具体的代码可以到Github上面参考
项目Demo链接
网友评论