前言
本文介绍ffmpeg最新版4.1在mac的编译为android的方法跟说明,编译多个so打包为libffmpeg.so。
编译流程
下载FFMpeg源代码地址:
准备好NDK
Android NDK 下载地址(推荐r17以下(包括r17c))
编写build for Android 脚本
在FFMpeg根目录新建sh文件,命名为:build_android.sh,复制脚本到build_android.sh, 内容如下:
# ndk环境
export NDK=/Users/ali/Library/Android/android-ndk-r17c
export SYSROOT=$NDK/platforms/android-21/arch-arm
export TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
CPU=armv7-a
ISYSROOT=$NDK/sysroot
ASM=$ISYSROOT/usr/include/arm-linux-androideabi
# 要保存动态库的目录,这里保存在源码根目录下的android/armv7-a
export PREFIX=$(pwd)/android/$CPU
ADDI_CFLAGS="-marm"
# 编译配置详解答
# 设置编译针对的系统,网上查到很多资料说编译前需要修改configure文件,设置这项后就不用修改了,系统会自动修改,效果一样。
#--target-os=linux \
# 编译后文件的输出目录
#--prefix=$PREFIX \
#--enable-cross-compile \
# 编译动态库,shared和static的开关是相对的。
#--enable-static \
#--disable-shared \
# 生成文档,以及相关的功能模块
#--disable-doc \
# 禁止编译可执行文件
#--disable-programs
#--disable-ffmpeg \
#--disable-ffplay \
#--disable-ffprobe \
#--disable-avdevice \
#--disable-doc \
#--disable-symver \
# 设置交叉编译器,按照实际路径修改就可以了。
#--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
# 设置编译器,不然会报错,系统默认会使用arm-linux-androideabi-clang,但是此编译器在NDK不存在,导致编译失败
#--cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \
#--nm=$TOOLCHAIN/bin/arm-linux-androideabi-nm \
# 设置编译so库的架构,当前设置为arm,可以根据实际需求修改
#--arch=arm \
# 设置编译针对的平台,可以根据实际需求进行设置,当前设置为最低支持android-21版本,arm架构。
#--sysroot=$SYSROOT \
#--extra-cflags="-I$ASM -isysroot $ISYSROOT -D__ANDROID_API__=21 -U_FILE_OFFSET_BITS -Os -fPIC -DANDROID -Wno-deprecated -mfloat-abi=softfp -marm" \
#--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
function build_android
{
echo -e "\033[32m build start \033[0m"
./configure \
--target-os=android \
--prefix=$PREFIX \
--enable-cross-compile \
--enable-static \
--disable-shared \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-avdevice \
--disable-doc \
--disable-symver \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \
--nm=$TOOLCHAIN/bin/arm-linux-androideabi-nm \
--arch=arm \
--sysroot=$SYSROOT \
--extra-cflags="-I$ASM -isysroot $ISYSROOT -D__ANDROID_API__=21 -U_FILE_OFFSET_BITS -Os -fPIC -DANDROID -Wno-deprecated -mfloat-abi=softfp -marm" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make -j16
make install
echo -e "\033[32m build successful \033[0m"
}
function merge
{
echo -e "\033[32m package start \033[0m"
# 打包
$TOOLCHAIN/bin/arm-linux-androideabi-ld \
-rpath-link=$SYSROOT/usr/lib \
-L$SYSROOT/usr/lib \
-L$PREFIX/lib \
-soname libffmpeg.so -shared -nostdlib -Bsymbolic --whole-archive --no-undefined -o \
$PREFIX/libffmpeg.so \
libavcodec/libavcodec.a \
libavfilter/libavfilter.a \
libavformat/libavformat.a \
libavutil/libavutil.a \
libswresample/libswresample.a \
libswscale/libswscale.a \
-lc -lm -lz -ldl -llog --dynamic-linker=/system/bin/linker \
$TOOLCHAIN/lib/gcc/arm-linux-androideabi/4.9.x/libgcc.a
# strip 精简文件
$TOOLCHAIN/bin/arm-linux-androideabi-strip $PREFIX/libffmpeg.so
echo -e "\033[32m package successful \033[0m"
}
build_android
merge
在Mac终端执行
./build_android.sh
相关流程说明
1、配置NDK相关环境
export NDK=/Users/ali/Library/Android/android-ndk-r17c
export SYSROOT=$NDK/platforms/android-21/arch-arm
export TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
CPU=armv7-a
ISYSROOT=$NDK/sysroot
ASM=$ISYSROOT/usr/include/arm-linux-androideabi
2、配置configure
./configure \
--target-os=android \
--prefix=$PREFIX \
--enable-cross-compile \
--enable-static \
--disable-shared \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-avdevice \
--disable-doc \
--disable-symver \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \
--nm=$TOOLCHAIN/bin/arm-linux-androideabi-nm \
--arch=arm \
--sysroot=$SYSROOT \
--extra-cflags="-I$ASM -isysroot $ISYSROOT -D__ANDROID_API__=21 -U_FILE_OFFSET_BITS -Os -fPIC -DANDROID -Wno-deprecated -mfloat-abi=softfp -marm" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
![14_38_08__05_09_2019.jpg](https://upload-images.jianshu.io/upload_images/17752287-4020d9b8d50be540.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![14_39_06__05_09_2019.jpg](https://upload-images.jianshu.io/upload_images/17752287-b3f7938542fe0c1f.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
3、执行编译
make clean
make -j16
make install
4、执行打包
function merge
{
echo -e "\033[32m package start \033[0m"
# 打包
$TOOLCHAIN/bin/arm-linux-androideabi-ld \
-rpath-link=$SYSROOT/usr/lib \
-L$SYSROOT/usr/lib \
-L$PREFIX/lib \
-soname libffmpeg.so -shared -nostdlib -Bsymbolic --whole-archive --no-undefined -o \
$PREFIX/libffmpeg.so \
libavcodec/libavcodec.a \
libavfilter/libavfilter.a \
libavformat/libavformat.a \
libavutil/libavutil.a \
libswresample/libswresample.a \
libswscale/libswscale.a \
-lc -lm -lz -ldl -llog --dynamic-linker=/system/bin/linker \
$TOOLCHAIN/lib/gcc/arm-linux-androideabi/4.9.x/libgcc.a
# strip 精简文件
$TOOLCHAIN/bin/arm-linux-androideabi-strip $PREFIX/libffmpeg.so
echo -e "\033[32m package successful \033[0m"
}
编译效果
如果大家编译效果一致,那么恭喜,编译成功,接下来就可以在Android平台上使用FFMpeg了;
思考&总结
1、关于修改configure,网上很多同学说需要修改configure,其实只要参数设置为--target-os=android,FFMpeg自动会处理文件路径相关问题;
修改前:
SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'
SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)'
修改后:
SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'
2、NDK17需要指定编译器,不然系统默认会使用arm-linux-androideabi-clang,但是此编译器在NDK不存在,导致编译失败
--cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \
--nm=$TOOLCHAIN/bin/arm-linux-androideabi-nm \
3、pkg-config not found,是编译过程中缺少pkg-config依赖,安装即可
在终端执行:
brew install pkg-config
4、其他一些编译错误,在mac上需要安装XCode,brewhome等环境
Xcode直接在apple官网或者App Store查找安装即可
brewhome可执行下面命令安装,命令会自动更新brew以及相关依赖
brew install automake fdk-aac git libtool libvorbis libvpx opus sdl shtool yasm texi2html theora wget x264 xvid lame libass
5、查看FFMpeg的版信息,打开版本信息所在文件--RELEASE
6、FFMpeg涉及面很广也深,刚开始接触只是初窥,后续还需要持续学习与实践才能逐步掌握,过程需要耐心]