在后面的Linux下ndk编译移植FFmpeg到Android平台文章中介绍了怎样将最基本的FFmpeg到Android平台。但只是简单的移植了FFmpeg,没有包含x264编码器,但是AAC编码器也只有默认的。在Android平台下使用FFmpeg进行RTMP推流(摄像头推流)中我实际上早已用到了x264编码器,但没有介绍怎样将x264集成到FFmpeg中。而本篇文章将解决这个问题,重点讲解怎样集成x264和libfdk-aac,其实也会有问题汇总。
为何要单独一篇文章来介绍怎样去移植FFmpeg、x264和fdk_aac呢?
万事开头难,第一步很难linux程序移植到android,但也是最重要的,不怕告诉你们linux程序移植到android,就仅仅编译这几个东西我足足花了两天时间去踩坑。对于有些编译出现各类问题造成没有成功的兄弟,可能特别的骨折积极性,严打学习这方面知识的积极性。所以我认为有必要重点讲解下这个环节
在步入这是内容之前我要指出一点,一定要注意安装版本,这个安装版本包括linux系统版本、FFmpeg版本、x264版本、libfdk-aac版本、ndk中android-api版本。你可能会由于版本不匹配造成编译出现各类问题,既然我早已把这种坑踩过了,希望你们不要再掉进去
同步开源库FFmpegSample,上面有我最新编译好的so和对应的编译脚本build_x264.sh,build_fdk.sh,build_ffmpeg.sh
文章围绕以下几点介绍
编译环境
[root@iZ94g6hanmqZ include]# lsb_release -a
LSB Version: :base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch
Distributor ID: CentOS
Description: CentOS release 6.8 (Final)
Release: 6.8
Codename: Final
[root@localhost /]# cat /etc/centos-release
CentOS Linux release 7.4.1708 (Core)
接出来到了真正编译的时侯了
编译x264
下载地址下载版本x264-snapshot-2-stable.tar
2.png
之后解压为x264目录linux命令ls,步入x264目录,新建build_x264.sh内容为:
#!/bin/bash
#NDK=/usr/local/android/ndk-bundle
NDK=/usr/local/app/android-ndk-r15c
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
PLATFORM=$NDK/platforms/android-16/arch-arm
PREFIX=./android
echo $NDK
echo $TOOLCHAIN
echo $PLATFORM
echo $PREFIX
function build_one
{
./configure
--prefix=$PREFIX
--enable-static
--disable-shared
--enable-pic
--disable-asm
--disable-cli
--host=arm-linux
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi-
--sysroot=$PLATFORM
}
build_one
之后给文件降低运行权限chmod+xbuild_x264.sh。剩下的就是配置编译安装啦。
./build_x264.sh
make -j4
make install
安装目录就在当前目录下生成android目录,其实库文件和头文件就有了
drwxr-xr-x 2 root root 4096 Jan 25 15:06 include
drwxr-xr-x 3 root root 4096 Jan 25 15:06 lib
编译libfdk-aac
先来几个问题:
3.png
下边即将步入编译fdk_aac
下载地址版本选择0.1.4
4.png
同样加压到fdk-aac-0.1.4目录,步入目录,新建build_fdk.sh内容为:
#!/bin/bash
NDK_HOME=/usr/local/app/android-ndk-r15c
ANDROID_API=android-14
SYSROOT=$NDK_HOME/platforms/$ANDROID_API/arch-arm
ANDROID_BIN=$NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/
CROSS_COMPILE=${ANDROID_BIN}/arm-linux-androideabi-
ARM_INC=$SYSROOT/usr/include
ARM_LIB=$SYSROOT/usr/lib
LDFLAGS=" -nostdlib -Bdynamic -Wl,--whole-archive -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,nocopyreloc -Wl,-soname,/system/lib/libz.so -Wl,-rpath-link=$ARM_LIB,-dynamic-linker=/system/bin/linker -L$NDK_HOME/sources/cxx-stl/gnu-libstdc++/libs/armeabi -L$NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86/arm-linux-androideabi/lib -L$ARM_LIB -lc -lgcc -lm -ldl "
FLAGS="--host=arm-androideabi-linux --enable-static --disable-shared"
export CXX="${CROSS_COMPILE}g++ --sysroot=${SYSROOT}"
export LDFLAGS="$LDFLAGS"
export CC="${CROSS_COMPILE}gcc --sysroot=${SYSROOT}"
./configure $FLAGS --prefix='/usr/local/app/fdk-aac-0.1.4/android'
剩下的就是配置编译安装啦。
./build_fdk.sh
make -j4
make install
安装目录就在当前目录下生成android目录,其实库文件和头文件就有了
drwxr-xr-x 2 root root 4096 Jan 25 15:06 include
drwxr-xr-x 3 root root 4096 Jan 25 15:06 lib
编译FFmpeg
FFmpeg版本3.2.4下载地址
下载完源码解压后,我们步入目录先更改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)'
这儿是更改编译完成后so文件的文件名格式
新建build_ffmpeg.sh脚本,内容
#!/bin/bash
NDK=/usr/local/app/android-ndk-r15c
SYSROOT=$NDK/platforms/android-16/arch-arm/
PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
function build_one
{
./configure --prefix=$PREFIX
--enable-shared
--cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
--disable-static
--disable-doc
--disable-ffserver
--disable-yasm
--enable-cross-compile
--enable-gpl
--enable-libx264
--enable-decoder=h264
--enable-encoder=libx264
--enable-libfdk-aac
--enable-encoder=libfdk_aac
--enable-decoder=libfdk_aac
--enable-nonfree
--cross-prefix="$TOOLCHAIN/bin/arm-linux-androideabi-"
--target-os=linux
--arch=arm
--sysroot=$SYSROOT
--extra-cflags="-Os -fpic $ADDI_CFLAGS"
--extra-ldflags="$ADDI_LDFLAGS"
$ADDITIONAL_CONFIGURE_FLAG
}
CPU=arm
PREFIX=$(pwd)/android/$CPU
ADDI_CFLAGS="-marm -I/usr/local/app/x264-snapshot-20140916-2245-stable/android/include -DANDROID -I/usr/local/app/fdk-aac-0.1.4/android/include"
ADDI_LDFLAGS="-L/usr/local/app/x264-snapshot-20140916-2245-stable/android/lib -L/usr/local/app/fdk-aac-0.1.4/android/lib"
build_one
之后给文件降低运行权限chmod+xbuild_ffmpeg.sh。剩下的就是配置编译安装啦。
./build_x264.sh
make -j4
make install
安装完以后我们最终的so包就生成了。在当前目录下的./android/arm下。
drwxr-xr-x 2 root root 4096 Jan 25 15:23 bin
drwxr-xr-x 10 root root 4096 Jan 25 15:11 include
drwxr-xr-x 3 root root 4096 Jan 25 15:23 lib
drwxr-xr-x 3 root root 4096 Jan 25 15:11 share
我们的动态库就在lib下了
-rwxr-xr-x 1 root root 12983912 Jan 25 15:23 libavcodec-57.so
lrwxrwxrwx 1 root root 16 Jan 25 15:23 libavcodec.so -> libavcodec-57.so
-rwxr-xr-x 1 root root 59384 Jan 25 15:23 libavdevice-57.so
lrwxrwxrwx 1 root root 17 Jan 25 15:23 libavdevice.so -> libavdevice-57.so
-rwxr-xr-x 1 root root 1877548 Jan 25 15:23 libavfilter-6.so
lrwxrwxrwx 1 root root 16 Jan 25 15:23 libavfilter.so -> libavfilter-6.so
-rwxr-xr-x 1 root root 1956464 Jan 25 15:23 libavformat-57.so
lrwxrwxrwx 1 root root 17 Jan 25 15:23 libavformat.so -> libavformat-57.so
-rwxr-xr-x 1 root root 443860 Jan 25 15:23 libavutil-55.so
lrwxrwxrwx 1 root root 15 Jan 25 15:23 libavutil.so -> libavutil-55.so
-rwxr-xr-x 1 root root 42276 Jan 25 15:23 libpostproc-54.so
lrwxrwxrwx 1 root root 17 Jan 25 15:23 libpostproc.so -> libpostproc-54.so
-rwxr-xr-x 1 root root 91532 Jan 25 15:23 libswresample-2.so
lrwxrwxrwx 1 root root 18 Jan 25 15:23 libswresample.so -> libswresample-2.so
-rwxr-xr-x 1 root root 406924 Jan 25 15:23 libswscale-4.so
lrwxrwxrwx 1 root root 15 Jan 25 15:23 libswscale.so -> libswscale-4.so
drwxr-xr-x 2 root root 4096 Jan 25 15:23 pkgconfig
这儿对脚本做个解释,降低了几个命令。
--enable-libx264
--enable-decoder=h264
--enable-encoder=libx264
--enable-libfdk-aac
--enable-encoder=libfdk_aac
--enable-decoder=libfdk_aac
要支持fdk_aac必须还加上
--enable-nonfree
--enable-gpl
最后就是制订x264fdk_aac的头文件和库文件的目录--extra-cflags加入头文件目录,--extra-ldflags包含库文件目录,也就是
ADDI_CFLAGS="-marm -I/opt/x264/android/include -DANDROID -I/opt/fdk-aac-0.1.4/android/include"
ADDI_LDFLAGS="-L/opt/x264/android/lib -L/opt/fdk-aac-0.1.4/android/lib"
到这儿我们就完成了整个编译。得到的so库除了有FFmpeg基础功能,还有x264和fdk_aac的编解码功能
踩坑历程configureFFmpeg提示找不到x264
听到这个问题,我开始很惊讶,我明明都配置正确了,后来查看config日志,提示找不到哪些log2技巧。后来发觉新版本的x264的config.h中启用了这个方式,所以你们按我选择的版本就没问题啦。
makeFFmpeg报错
libavcodec/libx264.c: In function 'x264_frame' :
libavcodec/libx264.c:282:9 error: 'x264_bit_depth' undeclared(first use in this function)
if(x264_bit_depth>8)
libavcodec/libx264.c: In function 'x264_init_static':
libavcodec/libx264.c:892.9 error: 'x264_bit_depth' undeclared(first use in this function)
if(x264_bit_depth== 8)
很显著没有找到x264_bit_depth这个变量。那咋整,还是版本不对应咯。你用的x264,FFmpeg可能不太兼容哦。
configureFFmpeg是faac不能用
这个上面早已提及了,FFmpeg早已不再支持libfaac啦。
编译好的so,置于android平台下使用时,提示找不到x264.so
这儿要注意,我在编译x264和fdk_aac时全部使用的静态编译linux命令vi,编下来的是静态库。这么最终我编译完FFmpeg后就不须要讲x264的so加入到android应用项目中。假如你是动态编译x264和fdk_aac这么你就得把这两个库的so也加入到android应用项目中。
注意编译x264和fdk_aac中间的参数--enable-static--disable-shared
到此所有讲解结束了,先预告下一篇,下一篇将介绍Android平台下使用FFmpeg进行AAC编译。上面会给你们解释为何要用fdk_aac,而不用默认的AAC编码器。