音视频开源库FFmpeg 的编译
Liunx下编译音视频开源库FFmpeg。
准备:
1.云主机 / 虚拟机(ubuntu)
2.NDK r16 下载地址 https://dl.google.com/android/repository/android-ndk-r16b-linux-x86_64.zip
3.FFmpeg 3.3.9 下载地址 http://www.ffmpeg.org/download.html
开始:
对于Android开发者编译FFmpeg掌握的知识还是比较广的,要掌握的知识包括c/c++,ndk,liunx,shell脚本,make语法,要能够看懂FFmpeg configure文件 对应写出编译的脚本。
把下载好的文件上传到ubuntu,进行解压
//解压
unzip android-ndk-r16b-linux-x86_64.zip //解压zip文件
tar -zxvf ffmpeg-3.3.9.tar.gz //解压gzip文件
配置liunx下ndk的环境变量 打开.bashrc文件
vim ~/.bashrc
在bashrc文件末尾处加上
export NDKROOT=/usr/ndk/android-ndk-r16b
export PATH=$NDKROOT:$PATH
更新环境变量
source ~/.bashrc
cd到ffmpeg 的解压目录修改configure文件 大概位置在文件的3305行,因为Android只能使用so结尾的库,修改使它编译成以.so结尾的文件。
#注释掉这几行
#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)'
执行以下configure文件
./configure --disable-yams
编译脚本的编写:build_android.sh
#!/bin/bash
export NDK_HOME=/usr/ndk/android-ndk-r16b
export PLATFORM_VERSION=android-19
function build_ffmpeg
{
echo "start build ffmpeg for $ARCH"
./configure --target-os=linux \
--prefix=$PREFIX --arch=$ARCH \
--disable-doc \
--enable-shared \
--disable-static \
--disable-yasm \
--disable-asm \
--disable-symver \
--enable-gpl \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--cross-prefix=$CROSS_COMPILE \
--enable-cross-compile \
--sysroot=$SYSROOT \
--enable-small \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS" \
$--
make clean
make
make install
echo "build ffmpeg for $ARCH finished"
}
#arm
ARCH=arm
CPU=arm
PREFIX=$(pwd)/android/$ARCH
TOOLCHAIN=$NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
CROSS_COMPILE=$TOOLCHAIN/bin/arm-linux-androideabi-
ADDI_CFLAGS="-marm"
SYSROOT=$NDK_HOME/platforms/$PLATFORM_VERSION/arch-$ARCH/
build_ffmpeg
这个脚本在NDK r16b报错,低版本能够编译成功的,如果要在低版本上使用需要改动,根据ndk的路径配置好交叉编译链的。例如我在NDK r14b编译脚本改动
export NDK_HOME=/usr/ndk/android-ndk-r14b
export PLATFORM_VERSION=android-9
如果交叉编译链路径出错是不能够编译成功的。
NDK r16b环境下在执行脚本为什么会出错呢?分析编译链的结构,发现android-ndk-r16b\platforms\android-19\arch-arm\usr下只有lib文件夹,没有include文件夹,相关include头文件则位于android-ndk-r16b\sysroot\usr\include下,修改–sysroot=$SYSROOT指向lib路径,并添加配置选项–sysinclude指向include文件夹,仍然编译失败。然后在网上搜索终于找到解决方法 利用make_standalone_toolchain的方式来制作编译链;
cd到ndk如下android-ndk-r16b\build\tools目录,有一个Python脚本make_standalone_toolchain.py,通过它可以自动生成我们需要的编译链环境
python make_standalone_toolchain.py --api 19 --install-dir /usr/ffmpeg/toolchain/android/linux-x86_64/ndk-r16/android-19/arm --arch arm --stl libc++ --force
这是我的(编译链环境安装路径)/usr/ffmpeg/toolchain/android/linux-x86_64/ndk-r16/android-19/arm你们可以自己自定义
有了新的编译环境 我们修改build_android.sh文件
#!/bin/bash
export NDK_HOME=/usr/ndk/android-ndk-r16b
export PLATFORM_VERSION=android-19
function build
{
echo "start build ffmpeg for $ARCH"
./configure --target-os=linux \
--prefix=$PREFIX --arch=$ARCH \
--disable-doc \
--enable-shared \
--disable-static \
--disable-yasm \
--disable-asm \
--disable-symver \
--enable-gpl \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--cross-prefix=$CROSS_COMPILE \
--enable-cross-compile \
--sysroot=$SYSROOT \
--enable-small \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
echo "build ffmpeg for $ARCH finished"
}
#arm
ARCH=arm
CPU=arm
PREFIX=$(pwd)/android/$ARCH
TOOLCHAIN=/usr/ffmpeg/toolchain/android/linux-x86_64/ndk-r16/android-19/arm
CROSS_COMPILE=$TOOLCHAIN/bin/arm-linux-androideabi-
ADDI_CFLAGS="-marm"
SYSROOT=$TOOLCHAIN/sysroot
build
用了正确的编译环境,和正确的配置接下来我们只要执行脚本就可以了
./build_android.sh
编译so结果.png
总结:
编译FFmpeg开源库要注意到的细节比较多,包括liunx系统一些工具的缺失,脚本的编写的,要严格按照shell语法来编写,换行时可能多了一个空格都会导致编译失败。NDK的版本不同交叉编译链的路劲也会有不同。
http://alientechlab.com/how-to-build-ffmpeg-for-android/
https://www.guoxiongfei.cn/csdn/1610.html