Mac下交叉编译FFmpeg3.4.5出Android的so包

在网上找了很多资料都从未编译成功过,一度特别失望;终于看了夏曹俊老师的视频播放器开发课之后也经过几番周折,最后成功了,在此总结一下,希望对在寻找资料的人有所帮助。

准备工作

这里两大主角就是:

  • FFmpeg(版本是3.4.5)
  • NDK(版本android-ndk-r15c)

特别注意这里版本是关键,下错了估计不行

我最开始下载了ffmpeg4.1不行,4.0.3还是不行,最后使用了3.4.5终于可以了;当然这里ndk我事先查资料知道了ndk16以后删除了一些东西,必须用15以及以下的才可以。

下载方式有很多,这里是官方的FFmpeg3.4.5文件,进入界面点击snapshot就能下载了,是一个.tar.gz文件,下载下来之后解压到某个目录即可,这个在哪都没有关系。

然后就是下载DNK,这个也是在官网下载就行,mac版ndk-r15c,下载好也是解压好就可以了,放哪也没有关系,但是最好放在一起。

我是建了一个ffmpeg目录,在目录下把ndk和ffmpeg-3.4.5放在一起的。

下载好之后,就可以执行命令了,并不需要修改configure文件,因为从3.4开始编译成android动态链接库的名称就是对的了。

编译过程

一般编译都有三部:

  • 执行configure文件
  • 执行make命令编译
  • 执行make install命令打包

但是我们在执行configure文件的时候一般都会加一些参数,这就是本文的重点,我整理成了编译脚本,配置了armv7-a和x86的。

首先创建一个build_android.sh的脚本文件,名字随意,然后将下边的脚本复制过去修改ndk的路径即可。

使用方法

将build_android.sh脚本放到ffmpeg3.4.5目录下,然后执行chmod +x build_android.sh命令给脚本增加权限,再直接执行./build_android.sh即可。

当然最好先看完我下边的讲解再执行也不晚,下边有脚本的解释。当然你也可以把脚本中NDK路径修改之后,再把make和make install命令注释掉之后运行这个脚本也是可以的。如果出错了再看看下边的解释,看看配置是否有问题。

脚本如下:

#!/bin/bash
echo "进入编译ffmpeg脚本"
NDK=/Users/arvin/develop/ffmpeg/ndk/android-ndk-r15c

function buildFF
{
    echo "开始编译ffmpeg"

    ARM=$1
    DST=$2
    ABI_PREFIX=$3
    PLATFORM=$NDK/platforms/android-21/arch-$ARM
    TOOLCHAIN=$NDK/toolchains/$DST-4.9/prebuilt/darwin-x86_64

    echo "ABI_PREFIX = ${ABI_PREFIX}"
    echo "PLATFORM = ${PLATFORM}"
    echo "TOOLCHAIN = ${TOOLCHAIN}"

    ./configure \
    --prefix=$PREFIX \
    --target-os=android \
    --cross-prefix=$TOOLCHAIN/bin/$ABI_PREFIX- \
    --arch=$ARM \
    --sysroot=$PLATFORM \
    --extra-cflags="$CFLAG" \
    --cc=$TOOLCHAIN/bin/$ABI_PREFIX-gcc \
    --nm=$TOOLCHAIN/bin/$ABI_PREFIX-nm \
    --enable-shared \
    --enable-runtime-cpudetect \
    --enable-gpl \
    --enable-small \
    --enable-cross-compile \
    --disable-debug \
    --disable-static \
    --disable-doc \
    --disable-ffmpeg \
    --disable-ffplay \
    --disable-ffprobe \
    --disable-ffserver \
    --disable-postproc \
    --disable-avdevice \
    --disable-symver \
    --disable-stripping \
    $ADD 
    make -j16
    make install
    echo "编译结束!"
}
###########################################################
echo "编译armv7-a支持neon和硬解码"
CPU=armv7-a
PREFIX=./android/$CPU-neon-hard
CFLAG="-I$PLATFORM/usr/include -fPIC -DANDROID -mfpu=neon -mfloat-abi=softfp "
ADD="--cpu=$CPU \
    --enable-asm \
    --enable-neon \
    --enable-jni \
    --enable-mediacodec \
    --enable-decoder=h264_mediacodec \
    --enable-hwaccel=h264_mediacodec "
buildFF arm arm-linux-androideabi arm-linux-androideabi

###########################################################
# echo "编译x86支持neon和硬解码"
# PREFIX=./android/x86-neon-hard
# CFLAG=""
# ADD="--extra-libs=-lgcc \
#     --disable-asm \
#     --enable-neon \
#     --enable-jni \
#     --enable-mediacodec \
#     --enable-decoder=h264_mediacodec \
#     --enable-hwaccel=h264_mediacodec "
# buildFF x86 x86 i686-linux-android

脚本解释

其中命令有一些比较重要的下边依次介绍。

  • #!/bin/bash这个注释表示这是一个bash脚本
  • echo是用来打印变量,方便调试的
  • NDK=你的ndk路径,这种方式是命名变量并赋值
  • function是定义函数,这里定义了一个buildFF函数,方便调用,后边可以加参数,在方法中通过$+数字获取,第一个参数就是$1,以此类推
  • PLATFORM是编译的架构,armv7-a就是arm架构,可以看到在ndk/platforms/android-某个版本目录下有很多arch-各种架构的文件
  • TOOLCHAINS是交叉编译的工具,选择的目录表示在哪个系统下编译成哪个系统架构,以编译成armv7-a架构为例,就表示在mac系统下编译成arm-linux-androideabi-49。其实自己也可以去ndk/toolchains目录下看一下,就大概明白了
  • 下边介绍configure的参数--prefix表示make install成功之后输出文件的路径
  • --target-os这里我们编译成android,很多文章写成linux,可能是在3.2以前可以吧,现在需要写成android,不然可能会有些头文件找不到
  • --cross-prefix就是交叉编译工具的前缀,可以去那个目录下,你就能看到为什么这样写了
  • --arch这个就是编译成什么架构,这里有两种armv7-a(参数需要写成arm)和x86的
  • --sysroot这个就是platform的路径,表示在这个平台下的库文件为基础
  • --extra-cflags是给gcc编译时增加的指令,在编译armv7-a架构的时候加上那些参数才能成功,其中-mfpu是指让gcc知道要使用neon协处理器,而在x86的编译时,这些指令都不能加,可能是x86架构下gcc对这些指令不支持,所以要去掉才能成功
  • --cc--nm就是指定gcc和nm的位置
  • 然后就是一系列--enable指令和--disable指令,就不一一介绍了
  • make -j16是开启16个线程去执行编译,这样会快很多

其中在执行脚本之前,大家可以先把脚本函数中的makemake install注释掉,因为编译过程也会花不少时间,注释掉之后执行,就只需要看配置是否有问题。没有error之后再解开注释执行。

注意在每次执行了脚本之后最好执行一下make clean清理一下。

对于armv7-a和x86的编译cflag和ADD的内容不一样,cflag在上文中说了,ADD部分,前者需要添加cpu类型,后者不需要,但是需要加上--extra-libs=-lgcc--disable-asm指令:

  • --extra-libs=-lgcc是为了让x86架构下gcc执行编译不报错
  • --disable-asm是为了让x86架构在as中使用的时候不会出现text relocation错误,意思是禁止汇编

到这里基本就讲述完成了,说起来内容不多,但是在不了解的情况下,出了错真的一点办法都没有。希望本文对还没有编译成功的人有帮助。

我也是刚接触这一块,若有不当之处请多多指教。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,817评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,329评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,354评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,498评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,600评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,829评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,979评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,722评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,189评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,519评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,654评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,940评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,762评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,993评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,382评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,543评论 2 349

推荐阅读更多精彩内容