ubuntu下编译FFmpeg so库

首先列出本次编译所需要的环境和源码版本:

  • 编译环境:VMware-15.5.6 + ubuntu-20.04.2.0
  • 编译工具:android-ndk-r22b
  • FFmpeg源码:ffmpeg-4.1.6

1. 搭建编译环境

1.1 安装Ubuntu

在Windows10电脑安装VMware,创建新的虚拟机Ubuntu,到官网下载需要版本安装即可,安装完成后执行以下命令:

  • apt-get update
  • apt-get install yasm
  • apt-get install pkg-config
  • apt-get install make
    如果安装失败,解决办法根据提示,加sudo,如:sudo apt-get install make

1.2 下载ndk

在/home下新建ffm文件夹,将ndk下载到 /home/ffm/目录下:
wget https://dl.google.com/android/repository/android-ndk-r22b-linux-x86_64.zip
下载完成后解压:
unzip android-ndk-r22b-linux-x86_64.zip

1.3 下载FFmpeg

将FFmpeg下载到 /home/ffm/目录下:
wget http://www.ffmpeg.org/releases/ffmpeg-4.1.6.tar.gz
下载完成后解压:
tar -zxvf ffmpeg-4.1.6.tar.gz

2. 编译FFmpeg

在开始编译FFmpeg之前,先简单介绍下交叉编译。引自百度百科的定义:交叉编译是在一个平台上生成另一个平台上的可执行代码,这里即是在Linux平台编译出Android平台可以使用的FFmpeg so库。
对于C/C++的编译,通常有两个工具 GCC 和 CLANG 。

  • GCC,是一个老牌的编译工具,不仅可以编译C/C++,也可以编译Java,Object-C,Go等语言。
  • CLANG,则是一个效率更高的C/C++编译工具,并且兼容GCC,Google在很早以前就开始建议使用clang进行编译,并且在ndk17以后,把GCC移除了,全面推行使用 CLANG 。

2.1 新建配置编译脚本

在ffmpeg-4.1.6源码根目录下新建脚本build.sh:vim build.sh


输入完成后,出现如下界面:

然后按下英文字母i, 底部就会出现INSERT, 表示当前可以输入文本信息,脚本内容如下:

#!/bin/bash
# 目标Android版本
API=21
ARCH=arm
CPU=armv7-a
#so库输出目录
PREFIX=$(pwd)/android/$CPU
# NDK的路径,根据自己的NDK位置进行设置
NDK=/home/root1/ffm/android-ndk-r22b
# 编译环境
SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
# 编译工具链路径
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin
OPTIMIZE_CFLAGS="-DBIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD -mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
configure()
{
    ./configure \
    --prefix=$PREFIX \
    --enable-cross-compile \
    --target-os=android \
    --arch=$ARCH \
    --cpu=$CPU \
    --sysroot=$SYSROOT \
    --cc=$TOOLCHAIN/armv7a-linux-androideabi$API-clang \
    --cxx=$TOOLCHAIN/armv7a-linux-androideabi$API-clang++ \
    --cross-prefix=$TOOLCHAIN/arm-linux-androideabi- \
    --disable-encoders \
    --disable-decoders \
    --enable-decoder=h264 \
    --enable-decoder=h264_mediacodec \
    --enable-decoder=mp3 \
    --enable-decoder=aac \
    --disable-muxers \
    --disable-demuxers \
    --enable-demuxer=flv \
    --enable-demuxer=sdp \
    --enable-demuxer=rtsp \
    --disable-filters \
    --disable-parsers \
    --enable-parser=aac \
    --enable-parser=h264 \
    --disable-bsfs \
    --enable-bsf=aac_adtstoasc \
    --enable-bsf=h264_mp4toannexb \
    --disable-protocols \
    --enable-protocol=file \
    --enable-protocol=http \
    --enable-protocol=rtmp \
    --disable-libsrt \
    --enable-neon \
    --enable-hwaccels \
    --enable-shared \
    --enable-jni \
    --enable-mediacodec \
    --disable-static \
    --disable-doc \
    --enable-ffmpeg \
    --disable-ffplay \
    --disable-ffprobe \
    --enable-avdevice \
    --disable-doc \
    --disable-symver \
    --extra-cflags="-Os -fpic $OPTIMIZE_CFLAGS" \
    --extra-ldflags="$ADDI_LDFLAGS" \
    $ADDITIONAL_CONFIGURE_FLAG
}

build()
{
    configure
    make clean
    make
    make install
}

build

编辑完成后按Esc键退出编辑模式,输入:wq保存退出,可以看到根目录下多了build.sh文件。
重点关注几个选项:

  • arch 选择机器架构
  • cpu 选择最低的cpu
  • target-os 设置目标系统
    在旧版本的 FFmpeg 中,对Android平台的支持并不是很完善,并没有android 这个target,所以在一些比较老的文章中都会提到,编译Android平台的so库,需要对 configure 做以下修改,否则会按照 linux 标准的方式输出so库,其命名方式和Android的so不一样,Android是无法加载的。
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)'

但是在新版本(至少从4.0开始)的FFmpeg中,这个问题已经被解决了,FFmpeg加入了android 这个 target,不再需要手动去修改,建议大家尽量使用较新的版本。

  • sysroot 用于配置交叉编译环境的根路径,编译的时候会默认从这个路径下去寻找usr/includeusr/lib这两个路径,进而找到相关的头文件和库文件。
    注意:这里的路径一定要写对,ndk路径,包括不同ndk版本下面的头文件和库文件位置可能有所不同,如果找不到就会编译失败。
    关于ndk的路径,这里有个坑,本来设置/home/ffm/android-ndk-r22b,一直提示找不到,编译失败,真实路径是/home/root1/ffm/android-ndk-r22b。大家可以右键查看ndk文件夹属性,即可看到真实路径,如下图所示:

  • cross-prefix 交叉编译工具的前缀

  • cc 指定使用何种C编译器(默认gcc)

  • cxx 指定使用何种C编译器(默认g++)
    FFmpeg 默认的编译工具是 gcc,ndk老版本中,使用的也是gcc编译,所以只要设置cross-prefix即可,要保证能找到gcc文件,比如ndk14中配置如下

TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
...
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \

对应的编译工具如下


ndk17以后,改用clang编译,需要设置cc和cxx选项,比如本例的ndk22。

TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin
...
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--cc=$TOOLCHAIN/armv7a-linux-androideabi$API-clang \
--cxx=$TOOLCHAIN/armv7a-linux-androideabi$API-clang++ \

对应的编译工具如下


可以根据自己的需求对脚本进行修改
查看所有编译配置选项:./configure --help
查看支持的解码器:./configure --list-decoders
查看支持的编码器:./configure --list-encoders
查看支持的硬件加速:./configure --list-hwaccels

2.2 启动编译

赋予脚本执行权限:chmod +x build.sh
执行脚本开始编译:./build.sh
等待编译完成,将会在源码根目录下的android/armv7-a/lib/下找到我们需要的.so文件了。

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

推荐阅读更多精彩内容