最近因为项目需求需要用到视频压缩处理,其实这个功能要实现出来很简单,到Github上拉几个知名的库分分钟搞定,但是那些比较知名的库功能很齐全所以包也比较大,arm、arm-v7a、arm64-v8a、x86、x86_64等基本全部做到了支持。为了解决这个问题顺便学习学习NDK入门方面的知识,本文仅仅分析arm-v7a架构的编译,其他的几种处理方式原理是一样的,有兴趣自己可以编译下。
编译环境
- Windows下编译(需要配置MinGW)
Android studio 2.3.3 (需要配置ndk环境)
如果你是linux或者Mac环境那是最方便了,本人偷懒懒得装个Ubuntu所以还是在Windows上编译了,Android环境下的jni开发有两种方式,一种是传统的配置Android.mk,另一种就是AS2.2及以后主推的配置cmakelist方法,这里使用新方法进行编译因为更加简单。
下载相关源码
我在桌面创建一个目录FFmpegInAndroid,里面创建如下几个目录:
x264文件放libx264的源码,fad-aac-0.1.5文件夹放libfdk-aac源码,ffmpeg-3.2.5文件夹放FFmpeg-3.2.5源码,buildoutput里面放我们编译上述源码的so文件及头文件。我们所做的工作就是把号称最好的视频编码器libx264和音频编码器libfdk-aac替换ffmpeg自带的音视频编码器,然后把ffmpeg编译出来丢到buildoutput文件里面去。
编译 x264 视频编码器
在buildoutput目录创建写一个编译x264的脚本x264_arm_build.sh
#!/bin/bash
# ndk 环境(改成自己的相应的环境)
NDK=E:/Android/sdk/ndk-bundle
SYSROOT=$NDK/platforms/android-14/arch-arm/
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64
# cpu 架构平台,若要编译 x86 则指定 x86
CPU=armv7-a
# 输出文件的前缀,也就是指定最后静态库输出到那里
PREFIX=$(pwd)/lib/x264/$CPU
# 优化参数
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
ADDI_CFLAGS=""
ADDI_LDFLAGS=""
# 因为当前目录在 build 目录,需要切换到 x264找到源码去执行 config
cd ../x264
function build_x264
{
./configure \
--prefix=$PREFIX \
--disable-shared \
--disable-asm \
--enable-static \
--enable-pic \
--enable-strip \
--host=arm-linux-androideabi \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--sysroot=$SYSROOT
--extra-cflags="-Os -fpic $ADDI_CFLAGS $OPTIMIZE_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make -j4
make install
}
# 执行编译指令
build_x264
编译请特别注意如果直接按照未修改的配置进行编译,结果编译出来的so文件类似libavcodec.so.55.39.101,版本号位于so之后,Android上似乎无法加载。因此需要按如下修改:
将x264/configure文件的
echo "SOSUFFIX=so" >> config.mak
echo "SONAME=libx264.so.$API" >> config.mak
echo "SOFLAGS=-shared -Wl,-soname,\$(SONAME) $SOFLAGS" >> config.mak
修改成
echo "SOSUFFIX=so" >> config.mak
echo "SONAME=libx264-$API.so" >> config.mak
echo "SOFLAGS=-shared -Wl,-soname,\$(SONAME) $SOFLAGS" >> config.mak
然后我们运行MinGW\msys\1.0目录下的msys.bat,cd到该目录执行x264_arm_build.sh脚本
chmod +x 命令是设置执行权限,出现上面的图说明编译成功了,现在去buildoutput/lib目录可以看到编译后生成的文件了。
编译 fad-aac 音频编码器
先在buildoutput目录创建一个配置脚本文件fdkacc_arm_build.sh
# 这个路径要根据自己环境修改
NDK=E:/Android/sdk/ndk-bundle
ANDROID_API=android-14
SYSROOT=$NDK/platforms/android-14/arch-arm/
ANDROID_BIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin
CROSS_COMPILE=${ANDROID_BIN}/arm-linux-androideabi-
CPU=armv7-a
# 输出文件的前缀,也就是指定最后静态库输出到那里
PREFIX=$(pwd)/lib/fdk_aac/$CPU
CFLAGS=""
FLAGS="--enable-static --host=arm-linux-androideabi --target=android --disable-asm "
export CXX="${CROSS_COMPILE}g++ --sysroot=${SYSROOT}"
export LDFLAGS=" -L$SYSROOT/usr/lib $CFLAGS "
export CXXFLAGS=$CFLAGS
export CFLAGS=$CFLAGS
export CC="${CROSS_COMPILE}gcc --sysroot=${SYSROOT}"
export A