Android利用ndk(r22)编译ffmpeg-4.2.1
音视频高级教程 - Darren老师:QQ326873713
课程链接:https://ke.qq.com/course/468797?tuin=137bb271
前言
编译ffmpeg4.2.1 (当前官网为4.3.1,编译方法是一样的),用最新版的ndk(当前为r22)
编译支持 x264/fdk-aac/mp3
后续支持X265, opus。
采用clang编译器,而不是传统gcc
该文档先以armv8-a架构为例,其他架构只需要修改对应的CPU架构。
进一步的工作,优化编译参数,降低cpu占用率。
准备工作
准备以下编译环境:
- VMware Workstation 14.1.1 build-7528167
- Ubuntu 16.04
下载的FFmpeg源码和ndk放到同一个目录,比如/home/lqf/android,确定了目录后,后续在设置ndk路径的时候要参照该目录。
- 下载ffmpeg 4.2.1 压缩文件
(ubuntu系统自带FireFox浏览器)
ffmpeg4.2.1
http://ffmpeg.org/releases/ffmpeg-4.2.1.tar.bz2
最新的版本编译方式是一致的。
![](https://img-blog.csdnimg.cn/img_convert/22755eb81b05a2d67939f2fc7e0ecd27.webp?x-oss-process=image/format,png#align=left&display=inline&height=339&margin=[object Object]&originHeight=339&originWidth=1257&size=0&status=done&style=none&width=1257)
- 下载最新的ndk
NDKr22
![image.png](https://img-blog.csdnimg.cn/img_convert/4541b2b394155b6020f1b9abc8742652.png#align=left&display=inline&height=162&margin=[object Object]&name=image.png&originHeight=323&originWidth=1065&size=70478&status=done&style=none&width=532.5)
下载:https://dl.google.com/android/repository/android-ndk-r22-linux-x86_64.zip
- 解压下载的两个文件
unzip android-ndk-r22-linux-x86_64.zip
tar jxf ffmpeg-4.2.1.tar.bz2
![image.png](https://img-blog.csdnimg.cn/img_convert/85881ae3c6d2245426ebb5b510179ed4.png#align=left&display=inline&height=48&margin=[object Object]&name=image.png&originHeight=64&originWidth=1112&size=12299&status=done&style=none&width=834)
开始编译
编译fdk-aac
进入ffmpeg-4.2.1目录
cd ffmpeg-4.2.1
下载fdk-aac
git clone --depth 1 https://github.com/mstorsjo/fdk-aac.git
cd fdk-aac
配置编译脚本armv8-a_build.sh
#!/bin/bash
NDK=/home/lqf/android/android-ndk-r22
HOST_TAG=linux-x86_64
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG
ANDROID_LIB_PATH="$(pwd)/android"
API=21
./autogen.sh
function build_android_arm
{
echo "build for android $CPU"
./configure \
--host=$HOST \
--disable-shared \
--enable-static \
--prefix="$ANDROID_LIB_PATH/$CPU"
make clean
make -j8
make install
echo "building for android $CPU completed"
}
CPU=armv8-a
HOST=aarch64-linux-android
export AR=$TOOLCHAIN/bin/aarch64-linux-android-ar
export AS=$TOOLCHAIN/bin/aarch64-linux-android-as
export LD=$TOOLCHAIN/bin/aarch64-linux-android-ld
export RANLIB=$TOOLCHAIN/bin/aarch64-linux-android-ranlib
export STRIP=$TOOLCHAIN/bin/aarch64-linux-android-strip
export CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
export CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
export CFLAGS="-Os -fpic $OPTIMIZE_CFLAGS"
export CPPFLAGS="-Os -fpic $OPTIMIZE_CFLAGS"
build_android_arm
增加执行权限
chmod +x armv8-a_build.sh
编译
执行脚本
./armv8-a_build.sh
报错
![image.png](https://img-blog.csdnimg.cn/img_convert/aed97d16c78827d88d1c2eec0d91f67a.png#align=left&display=inline&height=185&margin=[object Object]&name=image.png&originHeight=370&originWidth=981&size=49809&status=done&style=none&width=490.5)
注释
![image.png](https://img-blog.csdnimg.cn/img_convert/528c2babe336bd4be5af252fc67aa554.png#align=left&display=inline&height=46&margin=[object Object]&name=image.png&originHeight=92&originWidth=359&size=7075&status=done&style=none&width=179.5)
报错
![image.png](https://img-blog.csdnimg.cn/img_convert/e712db70cf074672c5bdd47f83f58495.png#align=left&display=inline&height=216&margin=[object Object]&name=image.png&originHeight=431&originWidth=1212&size=72678&status=done&style=none&width=606)
注释
![image.png](https://img-blog.csdnimg.cn/img_convert/1406d48eec026ed0a8a7a4087759486d.png#align=left&display=inline&height=92&margin=[object Object]&name=image.png&originHeight=183&originWidth=774&size=18779&status=done&style=none&width=387)
![image.png](https://img-blog.csdnimg.cn/img_convert/a3d934fd67236e94ecc1b84d4bcfb9a1.png#align=left&display=inline&height=82&margin=[object Object]&name=image.png&originHeight=164&originWidth=753&size=17879&status=done&style=none&width=376.5)
继续执行
./armv8-a_build.sh
编译后的文件在
/home/lqf/android/ffmpeg-4.2.1/fdk-aac/android/armv8-a
注意自己的路径
编译x264
进入ffmpeg-4.2.1目录
cd ffmpeg-4.2.1
下载x264
git clone --depth 1 https://gitee.com/mirrors_addons/x264.git
配置编译脚本armv8-a_build.sh
进入x264
cd x264
编写编译脚本armv8-a_build.sh
#!/bin/bash
NDK=/home/lqf/android/android-ndk-r22
HOST_TAG=linux-x86_64
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG
ANDROID_LIB_PATH="$(pwd)/android"
API=21
function build_android_arm
{
echo "build for android $CPU"
./configure \
--host=$HOST \
--disable-shared \
--enable-static \
--prefix="$ANDROID_LIB_PATH/$CPU" \
--enable-pic \
--enable-strip \
--extra-cflags="-fPIC"
make clean
make -j8
make install
echo "building for android $CPU completed"
}
CPU=armv8-a
HOST=aarch64-linux-android
#export AR=$TOOLCHAIN/bin/aarch64-linux-android-ar
#export AS=$TOOLCHAIN/bin/aarch64-linux-android-as
#export LD=$TOOLCHAIN/bin/aarch64-linux-android-ld
#export RANLIB=$TOOLCHAIN/bin/aarch64-linux-android-ranlib
#export STRIP=$TOOLCHAIN/bin/aarch64-linux-android-strip
export CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
export CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
build_android_arm
编译
执行脚本
./armv8-a_build.sh
编译后的文件在
/home/lqf/android/ffmpeg-4.2.1/x264/android/armv8-a
编译libmp3lame
进入ffmpeg-4.2.1目录
cd ffmpeg-4.2.1
下载libmp3lame
git clone --depth 1 https://gitee.com/hqiu/lame.git
配置编译脚本armv8-a_build.sh
配置编译脚本armv8-a_build.sh
#!/bin/bash
NDK=/home/lqf/android/android-ndk-r22
HOST_TAG=linux-x86_64
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG
ANDROID_LIB_PATH="$(pwd)/android"
API=21
function build_android_arm
{
echo "build for android $CPU"
./configure \
--host=$HOST \
--disable-shared \
--enable-static \
--prefix="$ANDROID_LIB_PATH/$CPU"
make clean
make -j8
make install
echo "building for android $CPU completed"
}
CPU=armv8-a
HOST=aarch64-linux-android
export AR=$TOOLCHAIN/bin/aarch64-linux-android-ar
export AS=$TOOLCHAIN/bin/aarch64-linux-android-as
export LD=$TOOLCHAIN/bin/aarch64-linux-android-ld
export RANLIB=$TOOLCHAIN/bin/aarch64-linux-android-ranlib
export STRIP=$TOOLCHAIN/bin/aarch64-linux-android-strip
export CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
export CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
OPTIMIZE_CFLAGS="-march=$CPU"
export CFLAGS="-Os -fpic $OPTIMIZE_CFLAGS"
export CPPFLAGS="-Os -fpic $OPTIMIZE_CFLAGS"
build_android_arm
编译
执行脚本
./armv8-a_build.sh
编译后的文件在
/home/lqf/android/ffmpeg-4.2.1/lame/android/armv8-a
编译FFmpeg
替换最终生成的so文件名
进入ffmpeg-4.2.1
# 将ffmpeg-4.2.1目录中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)'
创建编译脚本文件
创建一个armv8-a_build.sh脚本文件用来进行编译工作
#!/bin/bash
NDK=/home/lqf/android/android-ndk-r22
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64/
API=21
BASEPATH=$(cd `dirname $0`; pwd)
function build_android
{
echo "Compiling FFmpeg for $CPU"
./configure \
--prefix=$PREFIX \
--disable-neon \
--disable-hwaccels \
--disable-gpl \
--disable-postproc \
--enable-shared \
--enable-jni \
--disable-mediacodec \
--disable-decoder=h264_mediacodec \
--disable-static \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-avdevice \
--disable-doc \
--disable-symver \
--extra-cflags="-I$X264_INCLUDE -I$FDK_INCLUDE -I$MP3_INCLUDE" \
--extra-ldflags="-L$FDK_LIB -L$X264_LIB -L$MP3_LIB" \
--enable-nonfree \
--enable-gpl \
--enable-libfdk-aac \
--enable-libx264 \
--enable-libmp3lame \
--cross-prefix=$CROSS_PREFIX \
--target-os=android \
--arch=$ARCH \
--cpu=$CPU \
--cc=$CC
--cxx=$CXX
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $OPTIMIZE_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
echo "The Compilation of FFmpeg for $CPU is completed"
}
#armv8-a
ARCH=arm64
CPU=armv8-a
CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-
PREFIX=$(pwd)/android/$CPU
OPTIMIZE_CFLAGS="-march=$CPU"
#第三方库
FDK_INCLUDE=$BASEPATH/fdk-aac/android/$CPU/include
FDK_LIB=$BASEPATH/fdk-aac/android/$CPU/lib
X264_INCLUDE=$BASEPATH/x264/android/$CPU/include
X264_LIB=$BASEPATH/x264/android/$CPU/lib
MP3_INCLUDE=$BASEPATH/lame/android/$CPU/include
MP3_LIB=$BASEPATH/lame/android/$CPU/lib
build_android
#armv7-a
ARCH=arm
CPU=armv7-a
CC=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang
CXX=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++
SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
CROSS_PREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-
PREFIX=$(pwd)/android/$CPU
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
#build_android
#x86
ARCH=x86
CPU=x86
CC=$TOOLCHAIN/bin/i686-linux-android$API-clang
CXX=$TOOLCHAIN/bin/i686-linux-android$API-clang++
SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
CROSS_PREFIX=$TOOLCHAIN/bin/i686-linux-android-
PREFIX=$(pwd)/android/$CPU
OPTIMIZE_CFLAGS="-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32"
#build_android
#x86_64
ARCH=x86_64
CPU=x86-64
CC=$TOOLCHAIN/bin/x86_64-linux-android$API-clang
CXX=$TOOLCHAIN/bin/x86_64-linux-android$API-clang++
SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
CROSS_PREFIX=$TOOLCHAIN/bin/x86_64-linux-android-
PREFIX=$(pwd)/android/$CPU
OPTIMIZE_CFLAGS="-march=$CPU -msse4.2 -mpopcnt -m64 -mtune=intel"
#build_android
编译
- 添加执行执行
chmod +x armv8-a_build.sh
- 执行编译文件
./armv8-a_build.sh
编译完成查看文件
在/ffmpeg-4.2.1/android/目录下
![image.png](https://img-blog.csdnimg.cn/img_convert/22ce785abd92cb420591df7816ef7f32.png#align=left&display=inline&height=321&margin=[object Object]&name=image.png&originHeight=321&originWidth=795&size=56380&status=done&style=none&width=795)