最近在努力学习音视频相关东西,以备未来不时之需

在音视频处理领域有一个绕不过去的著名项目就是FFmpeg,这个项目基于 GPL 开源协议,官网

最新版本目前我在 mac 上无法编译,会报错

使用的总体环境如下:

Macos: 10.13.6 (17G65)
ffmpeg: 3.3.6
ndk: 15.2.4203891

引用外部源码(尝试失败)

初次尝试的时候,希望可以通过 CMakeLists 中配置头文件和库的方式,直接引用,发现可能需要拷贝所有源代码到项目中,但这样需要 copy 的东西很多,对于真实的项目来说也许可行,但 demo 项目就太复杂了,而且不方便今后的使用

交叉编译 so

这里有一个坑,就是 ndk 版本不能太低,因为之前使用过 ijkplayer,那个项目要求 11d 还是 11e 的 ndk 版本,我这次想直接用这个 ndk 版本,过程中会报很多错误,具体原因没有深究

然后使用我 android sdk 中带的 ndk 版本果断成功

这个是我的 ndk 版本,截至当前最新版本应该是 18.X

版本号在 ndk 中查看 propertis 文件可以看见

另一个叫法是 android-ndk-r15c

Pkg.Desc = Android NDK
Pkg.Revision = 15.2.4203891

ffmpeg 版本:我开始是下载的最新版本 4.1 版 ,结果编译不通过,在 udp.c 中报错了,通过网络搜索到一个原因,ffmpeg 版本太高了

通过下载了一个 ffmpeg-3.3.6 解决

另外,亲测最新的 NDKr18 并不能编译 3.3.6 会报一个

/Users/caijinglong/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc is unable to create an executable file.
C compiler test failed.

If you think configure made a mistake, make sure you are using the latest
version from Git.  If the latest version fails, report the problem to the
ffmpeg-user@ffmpeg.org mailing list or IRC #ffmpeg on irc.freenode.net.
Include the log file "config.log" produced by configure as this will help

换成 r15c 后分分钟钟成功

结论

在 mac 下,使用 ndk 15.2.4203891(r15c) + ffmpeg 3.3.6 一定可以成功,其他的环境不保证

ndk 下载

ffmpeg 下载

编译过程

脚本

使用的是楼上同学的脚本修改 ndk 路径

这里要注意 TMPDIR 对应的这个文件夹请提前建立好

#!/bin/bash
export TMPDIR=/Users/cai/code/c/ffmpeg/tempdir
NDK=/Users/cai/Library/Android/sdk/ndk-bundle

TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64

NDK_VERSION=android-14

PLATFORM=$NDK/platforms/$NDK_VERSION/arch-arm

echo "NDK=$NDK NDK_VERSION=$NDK_VERSION"

# darwin linux
function build_one {
./configure \
--target-os=linux \
--arch=$ARCH \
--prefix=$PREFIX \
--enable-shared \
--disable-static \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-doc \
--disable-symver \
--enable-cross-compile \
--cross-prefix=$CROSS_COMPILE \
--sysroot=$SYSROOT \
--extra-cflags="-fpic"

$ADDITIONAL_CONFIGURE_FLAG

make clean
make -j8
make install
}

ARCH=arm
CPU=arm
PREFIX=$(pwd)/android/$CPU
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
CROSS_COMPILE=$TOOLCHAIN/bin/arm-linux-androideabi-
SYSROOT=$NDK/platforms/$NDK_VERSION/arch-$ARCH

echo "PREFIX=${PREFIX}"
echo "TOOLCHAIN=${TOOLCHAIN}"
echo "CROSS_COMPILE=${CROSS_COMPILE}"
echo "SYSROOT=${SYSROOT}"

echo "******************************"

build_one

修改 ffmpeg 配置源码

使用 vi/文本编辑器 之类的东西打开 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)'

修改上面的为下面的

原始文件行为 3305~3308 行

编译

使用sh build_android.sh 打包 也可以用 chmod -x build_android.sh;./build_android.sh

然后等待完成就可以了

20190114163509.png

我这里是这样的

查看编译结果

我这里分别编译得到这样的结果

20190114163602.png

我这里是分别编译了 arm/v7a/arm64 的 so 文件,你只需要修改 sh 文件,将 CPU 分别设置即可打包出对应的类型

arm => armeabi
armeabi-v7a => armeabi-v7a
arm64-v8a => arm64-v8a

修改这两个为对应的 cpu 类型即可

ARCH=arm
CPU=arm

其实,正常来说 只需要一个 armeabi-v7a 就可以了,因为我是用的 flutter,为了兼容更多的设备,最好是有且只有 v7a 的 so 即可

后记

本篇是使用 mac 交叉编译出安卓可用的 so 库,下一篇会介绍如何将 so 置入