本次编译的环境和版本
- Mac OS
- Android
- NDK r21e
- ffmpeg-4.2.2
编译工具链
Android的NDK在r17c版本之后移除了GCC,不再支持GCC编译,r17c版本之后都使用CLANG进行编译。 NDK版本下载路径:developer.android.google.cn/ndk/downloa…
下载NDK之后,解压文件,进入NDK目录,之后来看下改版本的编译工具链。
该编译工具链中有两个重要的路径:
编译工具链目录:
toolchains/llvm/prebuilt/darwin-x86_64/bin
交叉编译环境目录:
toolchains/llvm/prebuilt/darwin-x86_64/sysroot
编译工具路径:
该截图未完整展示。
对于x86的CPU架构,编译工具是i686开头的文件,对于x86_64的CPU架构,编译工具是x86_64开头的文件。
根据不同的CPU架构区和不同的Android版本,区分了不同的clang工具,根据自己需要选择就好了。
例如:您要编译CPU架构是armeabi-v7a,最低支持Android21版本的ffmpeg,那么你选择的编译工具就是:
armv7a-linux-androideabi21-clang
armv7a-linux-androideabi21-clang++
下载FFmpeg
下载连接:ffmpeg.org/releases/
该地址ffmpeg所有的版本都有,可按需下载。本文采用的是4.2.2版本,所以选择ffmpeg-4.2.2.tar.gz 文件下载
下载好源码后,进入根目录,找到一个名为 congfigure 的文件,这是一个shell脚本,用于生成一些 FFmpeg 编译需要的配置文件。
网上很多教程会对此文件进行修改,但是3.4版本后不需要更改configure文件内容,下载解压后就ok,主要是后面脚本配置两步
创建编译脚本
在FFmpeg源码根目录新建编译脚本 build_android.sh
# 注意:
# 要想最后编译成一个so,则需要package_library任务并且配置 --enable-static
# 要想编译成多个so,则需要去掉package_library任务,并且配置 --enable-shared
# 可同时编译静态库和动态库
################################ arm64-v8a ################################
#!/bin/sh
# NDK 所在的路径
NDK=/Users/geely/FFmpeg/android-ndk-r21e
# 需要编译出的平台,这里是 arm64-v8a
ARCH=aarch64
CPU=arm64-v8a
# 支持的最低 Android API
API=21
# 编译后输出目录,在 ffmpeg 源码目录下的 /android/arm64-v8a
OUTPUT=$(pwd)/android/$CPU
# NDK 交叉编译工具链所在路径
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64
SYSROOT_L=$TOOLCHAIN/sysroot/usr/lib/aarch64-linux-android
GCC_L=$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/lib/gcc/aarch64-linux-android/4.9.x
build_arm64() {
echo "\033[32m Compiling FFmpeg for $CPU \033[0m"
./configure \
--target-os=android \
--prefix=$OUTPUT \
--arch=$ARCH \
--sysroot=$TOOLCHAIN/sysroot \
--enable-static \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-debug \
--disable-doc \
--disable-avdevice \
--enable-shared \
--enable-cross-compile \
--cross-prefix=$TOOLCHAIN/bin/aarch64-linux-android- \
--cc=$TOOLCHAIN/bin/aarch64-linux-android$API-clang \
--cxx=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++ \
--extra-cflags="-fpic -I$OUTPUT/include" \
--extra-ldflags="-lc -ldl -lm -lz -llog -lgcc -L$OUTPUT/lib"
make clean all
make -j8
make install
echo "\033[32m The Compilation of FFmpeg for $CPU is completed \033[0m"
}
package_library_arm64() {
echo "\033[32m package $CPU libffmpeg.so start \033[0m"
$TOOLCHAIN/bin/aarch64-linux-android-ld -L$OUTPUT/lib -L$GCC_L \
-rpath-link=$SYSROOT_L/$API -L$SYSROOT_L/$API -soname libffmpeg.so \
-shared -nostdlib -Bsymbolic --whole-archive --no-undefined -o $OUTPUT/libffmpeg.so \
-lavcodec -lavfilter -lswresample -lavformat -lavutil -lswscale -lgcc \
-lc -ldl -lm -lz -llog \
--dynamic-linker=/system/bin/linker
# 设置动态链接器,不同平台的不同,android 使用的是/system/bin/linker
echo "\033[32m package $CPU libffmpeg.so success \033[0m"
}
build_arm64
package_library_arm64
################################ armeabi-v7a ################################
#!/bin/sh
# NDK 所在的路径
NDK=/Users/geely/FFmpeg/android-ndk-r21e
# 需要编译出的平台,这里是 arm64-v8a
ARCH=arm
CPU=armeabi-v7a
# 支持的最低 Android API
API=21
# 编译后输出目录,在 ffmpeg 源码目录下的 /android/arm64-v8a
OUTPUT=$(pwd)/android/$CPU
# NDK 交叉编译工具链所在路径
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64
SYSROOT_L=$TOOLCHAIN/sysroot/usr/lib/arm-linux-androideabi
GCC_L=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/lib/gcc/arm-linux-androideabi/4.9.x
build_arm() {
echo "\033[32m Compiling FFmpeg for $CPU \033[0m"
./configure \
--target-os=android \
--prefix=$OUTPUT \
--arch=$ARCH \
--sysroot=$TOOLCHAIN/sysroot \
--enable-static \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-debug \
--disable-doc \
--disable-avdevice \
--enable-shared \
--enable-cross-compile \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--cc=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang \
--cxx=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++ \
--extra-cflags="-fpic -I$OUTPUT/include" \
--extra-ldflags="-lc -ldl -lm -lz -llog -lgcc -L$OUTPUT/lib"
make clean all
make -j8
make install
echo "\033[32m The Compilation of FFmpeg for $CPU is completed \033[0m"
}
package_library_arm() {
echo "\033[32m package $CPU libffmpeg.so start \033[0m"
$TOOLCHAIN/bin/arm-linux-androideabi-ld -L$OUTPUT/lib -L$GCC_L \
-rpath-link=$SYSROOT_L/$API -L$SYSROOT_L/$API -soname libffmpeg.so \
-shared -nostdlib -Bsymbolic --whole-archive --no-undefined -o $OUTPUT/libffmpeg.so \
-lavcodec -lavfilter -lswresample -lavformat -lavutil -lswscale -lgcc \
-lc -ldl -lm -lz -llog \
--dynamic-linker=/system/bin/linker
# 设置动态链接器,不同平台的不同,android 使用的是/system/bin/linker
echo "\033[32m package $CPU libffmpeg.so success \033[0m"
}
build_arm
package_library_arm
################################ x86 ################################
#!/bin/sh
# NDK 所在的路径
NDK=/Users/geely/FFmpeg/android-ndk-r21e
# 需要编译出的平台,这里是 arm64-v8a
ARCH=x86
CPU=x86
# 支持的最低 Android API
API=21
# 编译后输出目录,在 ffmpeg 源码目录下的 /android/arm64-v8a
OUTPUT=$(pwd)/android/$CPU
# NDK 交叉编译工具链所在路径
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64
SYSROOT_L=$TOOLCHAIN/sysroot/usr/lib/i686-linux-android
GCC_L=$NDK/toolchains/x86-4.9/prebuilt/darwin-x86_64/lib/gcc/i686-linux-android/4.9.x
build_x86() {
echo "\033[32m Compiling FFmpeg for $CPU \033[0m"
./configure \
--target-os=android \
--prefix=$OUTPUT \
--arch=$ARCH \
--sysroot=$TOOLCHAIN/sysroot \
--disable-asm \
--enable-static \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-debug \
--disable-doc \
--disable-avdevice \
--enable-shared \
--enable-cross-compile \
--cross-prefix=$TOOLCHAIN/bin/i686-linux-android- \
--cc=$TOOLCHAIN/bin/i686-linux-android$API-clang \
--cxx=$TOOLCHAIN/bin/i686-linux-android$API-clang++ \
--extra-cflags="-fpic -I$OUTPUT/include" \
--extra-ldflags="-lc -ldl -lm -lz -llog -lgcc -L$OUTPUT/lib"
make clean all
make -j8
make install
echo "\033[32m The Compilation of FFmpeg for $CPU is completed \033[0m"
}
package_library_x86() {
echo "\033[32m package $CPU libffmpeg.so start \033[0m"
$TOOLCHAIN/bin/i686-linux-android-ld -L$OUTPUT/lib -L$GCC_L \
-rpath-link=$SYSROOT_L/$API -L$SYSROOT_L/$API -soname libffmpeg.so \
-shared -nostdlib -Bsymbolic --whole-archive --no-undefined -o $OUTPUT/libffmpeg.so \
-lavcodec -lavfilter -lswresample -lavformat -lavutil -lswscale -lgcc \
-lc -ldl -lm -lz -llog \
--dynamic-linker=/system/bin/linker
# 设置动态链接器,不同平台的不同,android 使用的是/system/bin/linker
echo "\033[32m package $CPU libffmpeg.so success \033[0m"
}
build_x86
package_library_x86
################################ x86_64 ################################
#!/bin/sh
# NDK 所在的路径
NDK=/Users/geely/FFmpeg/android-ndk-r21e
# 需要编译出的平台,这里是 arm64-v8a
ARCH=x86_64
CPU=x86_64
# 支持的最低 Android API
API=21
# 编译后输出目录,在 ffmpeg 源码目录下的 /android/arm64-v8a
OUTPUT=$(pwd)/android/$CPU
# NDK 交叉编译工具链所在路径
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64
SYSROOT_L=$TOOLCHAIN/sysroot/usr/lib/x86_64-linux-android
GCC_L=$NDK/toolchains/x86_64-4.9/prebuilt/darwin-x86_64/lib/gcc/x86_64-linux-android/4.9.x
build_x86_64() {
echo "\033[32m Compiling FFmpeg for $CPU \033[0m"
./configure \
--target-os=android \
--prefix=$OUTPUT \
--arch=$ARCH \
--sysroot=$TOOLCHAIN/sysroot \
--enable-static \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-debug \
--disable-doc \
--disable-avdevice \
--enable-shared \
--enable-cross-compile \
--cross-prefix=$TOOLCHAIN/bin/x86_64-linux-android- \
--cc=$TOOLCHAIN/bin/x86_64-linux-android$API-clang \
--cxx=$TOOLCHAIN/bin/x86_64-linux-android$API-clang++ \
--extra-cflags="-fpic -I$OUTPUT/include" \
--extra-ldflags="-lc -ldl -lm -lz -llog -lgcc -L$OUTPUT/lib"
make clean all
make -j8
make install
echo "\033[32m The Compilation of FFmpeg for $CPU is completed \033[0m"
}
package_library_x86_64() {
echo "\033[32m package $CPU libffmpeg.so start \033[0m"
$TOOLCHAIN/bin/x86_64-linux-android-ld -L$OUTPUT/lib -L$GCC_L \
-rpath-link=$SYSROOT_L/$API -L$SYSROOT_L/$API -soname libffmpeg.so \
-shared -nostdlib -Bsymbolic --whole-archive --no-undefined -o $OUTPUT/libffmpeg.so \
-lavcodec -lavfilter -lswresample -lavformat -lavutil -lswscale -lgcc \
-lc -ldl -lm -lz -llog \
--dynamic-linker=/system/bin/linker
# 设置动态链接器,不同平台的不同,android 使用的是/system/bin/linker
echo "\033[32m package $CPU libffmpeg.so success \033[0m"
}
build_x86_64
package_library_x86_64