近期刚好用到FFmpeg来处理视频编码,由于网上各种版本的so库大部分都32位的,所以打算自己来编译32位和64位的库,我之前有写编译32位的库https://cloud.tencent.com/developer/article/1661468里面有关于ndk和32位的相关配置。今天主要是总结一下FFmpeg的64位的动态库编译。
版本下载:http://ffmpeg.org/releases/
FFmpeg的相关选项的介绍:https://blog.csdn.net/yzhang6_10/article/details/77104211?utm_source=blogxgwz7
先看看32位的编译脚本:采用的ndk14b的,编译版本是Android6.0,编译的abi是arm-linux-androideabi,sysroot是$NDK/platforms/android-21/arch-arm/ , ARCH是arm
#!/bin/bash
# 清空上次的编译
make clean
#你自己的NDK路径。
export NDK=/usr/ndk/android-ndk-r14b
# 设置你的android平台编译器的版本 这里采用Android6.0
export SYSROOT=$NDK/platforms/android-21/arch-arm/
#编译使用的toolchain
export TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
export NDK_ABI=arm-linux-androideabi
export CROSS=$TOOLCHAIN/bin/$NDK_ABI-
export ARCH=arm
export CPU=armv7a
# 这个是输出的路径
export PREFIX=$(pwd)/android/$CPU
export ADDI_CFLAGS="-marm"
function build_one
{
./configure \
--target-os=linux \
--prefix=$PREFIX \
--arch=$ARCH \
--disable-doc \
--enable-shared \
--disable-static \
--disable-asm \
--enable-pic \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-doc \
--disable-symver \
--disable-encoders \
--disable-muxers \
--enable-avresample \
--disable-pthreads \
--cross-prefix=$TOOLCHAIN/bin/$NDK_ABI- \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
}
rm -rf $PREFIX
make distclean
build_one
64位的编辑内容和32位不同的地方在:64位的编译脚本:编译的abi是aarch64-linux-android, SYSROOT是$NDK/platforms/android-21/arch-arm64/, TOOLCHAIN的要采用aarch64-linux-android-4.9, ARCH是aarch64
#!/bin/bash
# 清空上次的编译
make clean
#你自己的NDK路径。
export NDK=/usr/ndk/android-ndk-r14b
# 设置你的android平台编译器的版本 这里采用Android6.0
export SYSROOT=$NDK/platforms/android-21/arch-arm64/
#编译使用的toolchain
export TOOLCHAIN=$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64
export NDK_ABI=aarch64-linux-android
export CROSS=$TOOLCHAIN/bin/$NDK_ABI-
export ARCH=aarch64
export CPU=arm64
# 这个是输出的路径
export PREFIX=$(pwd)/android/$CPU
#export ADDI_CFLAGS="-marm=$CPU"
function build_one
{
./configure \
--target-os=linux \
--prefix=$PREFIX \
--arch=$ARCH \
--disable-doc \
--enable-shared \
--disable-static \
--disable-asm \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-doc \
--enable-avresample \
--disable-symver \
--cross-prefix=$TOOLCHAIN/bin/$NDK_ABI- \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-fPIE -pie" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
}
rm -rf $PREFIX
make distclean
build_one
解决方法:将libavcodec/aaccoder.c文件B0变量替换成b0
解决方法:将libavcodec/hevc_mvs.c文件的变量B0改成b0,xB0改成xb0,yB0改成yb0
解决方法:将libavcodec/opus_pvq.c文件的变量B0改成b0
分别得到arm64和armv7a的像个项目
2.配置CMakeLists.txt,引入FFmpeg的库
# 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)
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).
native-lib.cpp )
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 )
set(LIB_PATH ${PROJECT_SOURCE_DIR}/../../../libs)
include_directories(${LIB_PATH}/include)
set(DIR ${LIB_PATH}/${ANDROID_ABI})
MESSAGE("路径==" ${LIB_PATH})
MESSAGE("路径==" ${DIR})
# 开始添加FFmpeg的相关库的依赖
# 添加编码库
add_library(avcodec-58
SHARED
IMPORTED)
set_target_properties(
avcodec-58
PROPERTIES IMPORTED_LOCATION
${DIR}/libavcodec-58.so
)
# 添加各种设备的输入输出的库
add_library(avdevice-58
SHARED
IMPORTED)
set_target_properties(
avdevice-58
PROPERTIES IMPORTED_LOCATION
${DIR}/libavdevice-58.so
)
# 添加滤镜特效处理库
add_library(avfilter-7
SHARED
IMPORTED)
set_target_properties(
avfilter-7
PROPERTIES IMPORTED_LOCATION
${DIR}/libavfilter-7.so
)
# 添加封装格式处理库
add_library(avformat-58
SHARED
IMPORTED)
set_target_properties(
avformat-58
PROPERTIES IMPORTED_LOCATION
${DIR}/libavformat-58.so
)
# 添加工具库
add_library(avutil-56
SHARED
IMPORTED)
set_target_properties(
avutil-56
PROPERTIES IMPORTED_LOCATION
${DIR}/libavutil-56.so
)
# 添加
add_library(avresample-4
SHARED
IMPORTED)
set_target_properties(
avresample-4
PROPERTIES IMPORTED_LOCATION
${DIR}/libavresample-4.so
)
# 添加音频采样数据格式转换库
add_library(swresample-3
SHARED
IMPORTED)
set_target_properties(
swresample-3
PROPERTIES IMPORTED_LOCATION
${DIR}/libswresample-3.so
)
# 添加音频采样数据格式转换库
add_library(swscale-5
SHARED
IMPORTED)
set_target_properties(
swscale-5
PROPERTIES IMPORTED_LOCATION
${DIR}/libswscale-5.so
)
# 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.
native-lib
avcodec-58
avdevice-58
avfilter-7
avformat-58
avutil-56
avresample-4
swresample-3
swscale-5
# Links the target library to the log library
# included in the NDK.
${log-lib} )
3.build.gradle 的配置(这边是因为只导入64位的,所以需要配置):
externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions"
abiFilters "arm64-v8a"//, "armeabi-v7a" //, "arm64-v8a", "x86", "x86_64"
}
}
ndk{
abiFilters "arm64-v8a"
}
4.Java代码中的加载FFmpeg的库
static {
System.loadLibrary("avcodec-58");
System.loadLibrary("avdevice-58");
System.loadLibrary("avfilter-7");
System.loadLibrary("avformat-58");
System.loadLibrary("avutil-56");
System.loadLibrary("avresample-4");
System.loadLibrary("swresample-3");
System.loadLibrary("swscale-5");
System.loadLibrary("native-lib");
}
问题:编译的时候报
More than one file was found with OS independent path 'lib/arm64-v8a/libavformat-58.so'
解决方法:在build.gradle下添加
android{
....
packagingOptions {
pickFirst 'lib/arm64-v8a/libavcodec-58.so'
pickFirst 'lib/arm64-v8a/libavdevice-58.so'
pickFirst 'lib/arm64-v8a/libavfilter-7.so'
pickFirst 'lib/arm64-v8a/libavformat-58.so'
pickFirst 'lib/arm64-v8a/libavresample-4.so'
pickFirst 'lib/arm64-v8a/libavutil-56.so'
pickFirst 'lib/arm64-v8a/libswresample-3.so'
pickFirst 'lib/arm64-v8a/libswscale-5.so'
}
}
以上就是编译FFmpeg的32位和64位动态库,以及导入android项目的使用的内容。关于FFmpeg的编译真的很麻烦,如果需要编译某个版本,以及对应需要的库包:尽量确认下,ndk的版本,编译的选项的内容。以上是个人的一些FFmpeg的使用经验和大家分享,有问题欢迎指出。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。