准备工作
在开始正式的编译工作之前,需要准备好一下几个工具:
Yasm
Yasm是一个完全重写的MASM汇编器,编译FFmpeg时,需要借助Yasm生成二进制数据。[1]
如果还未安装Yasm,可以通过一下命令进行安装:
brew install yasm
NDK
Android NDK是一套工具集,可以使Android应用能够使用C和C++代码,编译FFmpeg时,需要借助NDK来实现交叉编译。我用的NDK版本是android-ndk-r20b
。[2]
编译步骤
1.下载FFmpeg源码
通过git直接拉取源码:
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg
我拉取下来的源码工程的最新tag是n4.5-dev
。
2.修改配置文件
在不修改FFmpeg默认配置的情况下,编译出来的动态库文件的文件名会存在一个问题,即文件名中.so后面还会跟上一串版本号,如:libavcodec.so.x.y.z
,其中还x.y.z是一串版本号,这在Android平台中是不能被正常识别的,因此需要修改配置文件相关部分的代码,以保证编译出来的动态库文件的文件名是以.so结尾的。
FFmpeg源码根目录下有一个configure
文件,打开后找到以下代码:
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)'
3.编写编译脚本
接下来需要编写编译FFmpeg的shell脚本。
我们在FFmpeg源码根目录下创建一个脚本文件,文件名随意,例如我这里的文件名为build_android.sh
,脚本内容如下[3]:
#!/bin/bash
make clean
set -e
archbit=64
if [ $archbit -eq 64 ];then
echo "build for 64bit"
ARCH=aarch64
CPU=armv8-a
API=21
PLATFORM=aarch64
ANDROID=android
CFLAGS=""
LDFLAGS=""
else
echo "build for 32bit"
ARCH=arm
CPU=armv7-a
API=16
PLATFORM=armv7a
ANDROID=androideabi
CFLAGS="-mfloat-abi=softfp -march=$CPU"
LDFLAGS="-Wl,--fix-cortex-a8"
fi
export NDK=/Users/xiaoyu/Library/Android/sdk/ndk/android-ndk-r20b
export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64/bin
export SYSROOT=$NDK/toolchains/llvm/prebuilt/darwin-x86_64/sysroot
export CROSS_PREFIX=$TOOLCHAIN/$ARCH-linux-$ANDROID-
export CC=$TOOLCHAIN/$PLATFORM-linux-$ANDROID$API-clang
export CXX=$TOOLCHAIN/$PLATFORM-linux-$ANDROID$API-clang++
export PREFIX=$(pwd)/android/$CPU
function build_android {
./configure \
--prefix=$PREFIX \
--cross-prefix=$CROSS_PREFIX \
--target-os=android \
--arch=$ARCH \
--cpu=$CPU \
--cc=$CC \
--cxx=$CXX \
--nm=$TOOLCHAIN/$ARCH-linux-$ANDROID-nm \
--strip=$TOOLCHAIN/$ARCH-linux-$ANDROID-strip \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="$CFLAGS" \
--extra-ldflags="$LDFLAGS" \
--extra-ldexeflags=-pie \
--enable-runtime-cpudetect \
--disable-static \
--enable-shared \
--disable-ffprobe \
--disable-ffplay \
--disable-ffmpeg \
--disable-debug \
--disable-doc \
--enable-avfilter \
--enable-decoders \
$ADDITIONAL_CONFIGURE_FLAG
make
make install
}
build_android
脚本内容中的
export NDK=/Users/xiaoyu/Library/Android/sdk/ndk/android-ndk-r20b
指明了NDK的路径,须替换为自己的NDK路径。
4.执行编译
保存build_android.sh
文件的内容后,在终端访问FFmpeg源码根目录执行如下命令进行编译:
./build_android.sh
编译开始后,在终端会不断输出编译信息,截取一段编译信息如下:
编译时间较长,大概二十分钟左右,可以趁这段时间干点别的事情。
5.编译完成
编译完成后,FFmpeg源码目录下多了一个android
目录,android
目录下包含了FFmpeg各模块的动态库文件以及需要include的头文件。
常见问题
1.编译后找不到libpostproc模块
需在编译脚本中增以下配置项:
--enable-postproc \
--enable-gpl \
参考资料
-
FFmpegAndroid(https://github.com/xufuji456/FFmpegAndroid) ↩︎