在Mac上编译基于Android平台的FFmpeg源码

在Mac上编译基于Android平台的FFmpeg源码
作者:小赵栏目:FFmpeg实战2023-03-31 15:12975
在Mac上编译基于Android平台的FFmpeg源码
这段时间开始研究音视频编解码的相关知识,自然少不了学习FFmpeg这个开源项目。网上编译FFmpeg源码有很多教程,但是大部分都过时了,编译的时候还会遇到一大堆错误,踩了不少坑。因此总结了此文章,方便大家后续查阅。

1、下载NDK和FFmpeg
编译Android平台的FFmpeg需要下载NDK和FFmpeg源码:

首先下载NDK,目前官方最新稳定版是r20的版本,但是建议不要下最新的。这里我们为了顺利编译,可以下载r17及以下的版本,这里我们下载了r17c版本,为什么?请看后面的报错处理环节。

然后去FFmepg官网下载最新的源码,目前最新版是ffmpeg-4.1.3.tar.bz2。

2、编写configure配置脚本
编译FFmpeg源码需要通过configure脚本来进行配置,后期根据项目需求可对FFmpeg进行各种裁剪,因此我们可以通过配置脚本来实现。通过指令./configure --help我们可以查看所支持的配置项,网上很多文章有介绍这里就不展开了。

新建build_android.sh文件,并输入以下脚本内容来帮助我们编译FFmpeg。注意更新下第一行的NDK路径修改为你本地下载的r17c路径即可:

#!/bin/bash
NDK=/Users/codezjx/Android/android-ndk-r17c
SYSROOT=$NDK/platforms/android-21/arch-arm
ISYSROOT=$NDK/sysroot
ASM=$ISYSROOT/usr/include/arm-linux-androideabi
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
PREFIX=$(pwd)/android/armv7-a
CROSS_PREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-
build_android()
{
    ./configure \
    --prefix=$PREFIX \
    --enable-shared \
    --disable-static \
    --disable-doc \
    --disable-ffmpeg \
    --disable-ffplay \
    --disable-ffprobe \
    --disable-avdevice \
    --disable-symver \
    --cross-prefix=$CROSS_PREFIX \
    --target-os=android \
    --arch=arm \
    --enable-cross-compile \
    --sysroot=$SYSROOT \
    --extra-cflags="-I$ASM -isysroot $ISYSROOT -D__ANDROID_API__=21 -Os -fpic -marm -march=armv7-a"
    make clean
    make
    make install
}
build_android
3、执行编译并生成.so文件
执行以下指令开始编译FFmpeg

$ chmod +x build_android.sh
$ ./build_android.sh
若最后没有报错,显示以下log,则证明编译成功,会在android/armv7-a下生生成我们需要的.so库和相关的头文件,这个路径也正是我们在--prefix中配置的路径

...
INSTALL libavutil/twofish.h
INSTALL libavutil/version.h
INSTALL libavutil/xtea.h
INSTALL libavutil/tea.h
INSTALL libavutil/lzo.h
INSTALL libavutil/avconfig.h
INSTALL libavutil/ffversion.h
INSTALL libavutil/libavutil.pc
最终android/armv7-a的目录结构大概是这样的:

├── include
│   ├── libavcodec
│   ├── libavfilter
│   ├── libavformat
│   ├── libavutil
│   ├── libswresample
│   └── libswscale
├── lib
│   ├── libavcodec.so
│   ├── libavfilter.so
│   ├── libavformat.so
│   ├── libavutil.so
│   ├── libswresample.so
│   ├── libswscale.so
│   └── pkgconfig
└── share
    └── ffmpeg
4、踩坑环节
由于我们这里编译的是最新的FFmpeg源码,网上的脚本很多都过时了,要不就是跟NDK版本不搭,编译的时候会遇到很多问题,这里列出我编译时遇到的一些问题,这样大家也能更清晰的知道为什么上面的build_android.sh要这么配置。

Tips:在编译FFmpeg的时候难免会遇到很多问题,控制台的错误信息可能不够详细,这个时候我们可以打开ffbuild/config.log这个log文件查看更细致的日志信息,可帮助我们更快的定位问题。

4.1 错误1:C compiler test failed.
/Users/codezjx/Android/android-sdk-macosx/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.
在NDK升级到r18及以后,官方移除了GCC采用了Clang作为默认的交叉编译器,具体可看这里Changelog-r18。而FFmpeg的编译默认选择的是GCC来进行编译,所以当configure脚本根据路径去查找arm-linux-androideabi-gcc这个可执行文件的时候,发现找不到了,这也是为啥上面我们选择r17c版本的NDK来编译的原因。

4.2 错误2:Unknown option “–disable-ffserver”
Unknown option "--disable-ffserver".
See ./configure --help for available options.
在FFmpeg4.0.x版本后已经移除掉--disable-ffserver这个配置项了,如果用的是网上的旧脚本,就会报这个错误,移除掉就好。

4.3 错误3:error: request for member ‘s_addr’ in something not a structure or union
libavformat/udp.c: In function 'udp_set_multicast_sources':
libavformat/udp.c:290:28: error: request for member 's_addr' in something not a structure or union
         mreqs.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
                            ^
libavformat/udp.c:292:32: error: incompatible types when assigning to type '__be32' from type 'struct in_addr'
             mreqs.imr_interface= ((struct sockaddr_in *)local_addr)->sin_addr;
                                ^
libavformat/udp.c:294:32: error: request for member 's_addr' in something not a structure or union
             mreqs.imr_interface.s_addr= INADDR_ANY;
                                ^
libavformat/udp.c:295:29: error: request for member 's_addr' in something not a structure or union
         mreqs.imr_sourceaddr.s_addr = ((struct sockaddr_in *

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值