Android cmake编译FFmpeg
项目地址
通过阅读本文,你将学到以下内容:
- 如何编译多种CPU指令集的FFmpeg动态库
- 如何配置CMakeLists.txt和build.gradle构建Android项目
编译环境
- ndk-r16
- ffmpeg-4.0.2
一、交叉编译FFmpeg生成动态库
FFmpeg是一个强大的音视频处理库,我们有时候只需要用到这个库的部分功能,因此我们需要通过configure的一些选项对它进行裁剪。此外,我们还需要配置生成哪种CPU指令集的动态库、生成的动态库在什么操作系统上使用以及一些编译选项等。
一个支持armeabi-v7a、arm64-v8a、x86和x86_64四种CPU指令集的FFmpeg编译脚本,内容如下:
#!/bin/sh
# build.sh
# Builds all supported architectures of FFmpeg for Android.
# Versions: NDK - r16b, FFmpeg - 4.0.2
NDK=/Users/chenzhichang/Downloads/android-ndk-r16b
# MacOS:darwin-86_64
HOST=darwin-x86_64
# Takes three arguments:
# First: ARCH, supported values: armeabi-v7a, arm64-v8a, x86, x86_64
# Second: platform level. Range: 14-19, 21-24, 26-28
# Third: additinal configuration flags. Already present flags: --enable-cross-compile --disable-static --disable-programs --disable-doc --enable-shared --enable-protocol=file --enable-pic --enable-small
build () {
ARCH=$1
LEVEL=$2
if [ ! $ARCH ]; then
ARCH=armeabi-v7a
fi
if [ ! $LEVEL ]; then
LEVEL=21
fi
ISYSROOT=$NDK/sysroot
PLATFORM_ARCH=
CFLAGS=
TARGET=
TOOLCHAIN_FOLDER=
CONFIGURATION="--disable-asm \
--enable-cross-compile \
--disable-static \
--disable-programs \
--disable-doc \
--enable-shared \
--enable-protocol=file \
--enable-pic \
--enable-small \
--disable-devices \
$3"
case $ARCH in
"armeabi-v7a")
TARGET="arm-linux-androideabi"
CFLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=neon"
PLATFORM_ARCH="arm"
TOOLCHAIN_FOLDER="arm-linux-androideabi"
;;
"arm64-v8a")
TARGET="aarch64-linux-android"
CFLAGS="-march=armv8-a"
PLATFORM_ARCH="arm64"
CONFIGURATION="$CONFIGURATION --disable-pthreads"
TOOLCHAIN_FOLDER="aarch64-linux-android"
;;
"x86")
TARGET="i686-linux-android"
CFLAGS="-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32"
PLATFORM_ARCH="x86"
TOOLCHAIN_FOLDER="x86"
;;
"x86_64")
TARGET="x86_64-linux-android"
CFLAGS="-march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel"
PLATFORM_ARCH="x86_64"
TOOLCHAIN_FOLDER="x86_64"
;;
esac
CROSS_PREFIX=$NDK/toolchains/$TOOLCHAIN_FOLDER-4.9/prebuilt/$HOST/bin/$TARGET-
ASM=$ISYSROOT/usr/include/$TARGET
SYSROOT=$NDK/platforms/android-$LEVEL/arch-$PLATFORM_ARCH/
PREFIX="android/$ARCH"
./configure --prefix=$PREFIX \
$CONFIGURATION \
--cross-prefix=$CROSS_PREFIX \
--arch=$PLATFORM_ARCH \
--target-os=android \
--sysroot=$SYSROOT \
--extra-cflags="$CFLAGS -I$ASM -isysroot $ISYSROOT -D__ANDROID_API__=$LEVEL -Wfatal-errors -U_FILE_OFFSET_BITS -Os -fPIC -DANDROID -D__thumb__ -Wno-deprecated"
make clean
make -j4
make install
}
#build "armeabi-v7a" "21"
#build "arm64-v8a" "21"
#build "x86_64" "21"
#build "x86" "21"
这个脚本的用法很简单,只需要将该脚本文件拷贝到ffmpeg源码的根目录下,将脚本中的NDK变量值改为你的电脑上NDK所在的路径。如果你的电脑不是Mac,则还需要修改HOST变量值。最后执行下面这条命令即可。其中armeabi-v7a表示CPU指令集,21表示Android版本。
./build.sh armeabi-v7a 21
在这里简单介绍一下关于此脚本的一些配置项,从而方便你能够根据你的需求来修改这个脚本:
- –prefix:指定编译输出的文件路径
- –target-os:指定目标操作系统
- –disable-static:禁止生成静态库
- –disable-programs:禁止生成ffplay、ffmpeg等可执行文件
- –disable-doc:禁止生成文档
- –enable-shared:生成动态动态链接库
- –enable-cross-compile:开启交叉编译(跨平台编译)
执行此脚本,最终生成文件如下:
二、创建NDK项目并引入FFmpeg动态库
创建一个NDK项目,然后将生成的ffmpeg动态库文件和头文件拷贝到libs文件夹,最终项目结构如下图。
三、配置build.gradle
需要配置的内容如下:
- 配置so库的路径
- 配置cmake编译选项和支持的CPU指令集,其中-Wno-deprecated-declarations选项用于忽略使用废弃API的编译警告。
- 配置CMakeLists.txt文件的路径
最终配置如下:
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.chenzhichang.testffmpeg"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
//配置so库的路径
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
//配置cmake编译选项和支持的CPU指令集
externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions -Wno-deprecated-declarations"
}
ndk{
abiFilters "armeabi-v7a", "x86_64", "x86"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
//配置CMakeLists.txt文件的路径
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
四、配置CMakeLists.txt
配置如下:
cmake_minimum_required(VERSION 3.4.1)
find_library( log-lib
log )
# 定义变量
set(distribution_DIR .