# Mac编译
第一次接入FFmpeg,搞了整整一天,生成so库,可谓一波三折,功夫不负有心人有心人,终于搞定了。网上很多方案都是基于ndk14之前生成的,最新版本的ndk21和最新版本的FFmpeg4.3.1用不了,错误很大,搞了好一阵子发现在Linux系统中一直报错,刚刚开始以为c编译器没有,于是安装了,yum install yasm和nasm但是还是报错,然后把ndk换成ndk14才可以编译了,但是问题又来了,虽然编译成功了但是没有生成so库文件内容。最后通过日志分析,才知道在ndk版本16开始c编译器已经被取消,使用的是clang编译,于是重新有引入新的ndk21,才搞定。
一、编译环境
FFmpeg4.3.1版本变化内容比较多,实践起来资料比较少,发现了很多问题,因此采用最常用的FFmpeg4.2.2。对于C/C++的编译,通常有两个工具 GCC 和 CLANG 。CLANG 则是更高效的C/C++编译工具,Google在NDK17 以后,把 GCC 移除了,全面推行使用 CLANG 。下面使用CLANG编译。
1、我的编译环境:
- ffmpeg-4.2.2.tar.bz2
- Mac
- NDK21.1.6352462
- QIOO855手机
2、查看手机支持的CUP:
adb shell cat /proc/cpuinfo
adb shell getprop ro.product.cpu.abi
- ARCH=arm64
- CPU=armv8-a
- TOOL_CPU_NAME=aarch64
事实上这也是目前绝大多数手机都支持的CUP架构。
3、编译工具链目录:
/Users/xxx/Library/Android/sdk/ndk/21.1.6352462/toolchains/llvm/prebuilt/darwin-x86_64/bin
4、交叉编译环境目录:
/Users/xxx/Library/Android/sdk/ndk/21.1.6352462/toolchains/llvm/prebuilt/darwin-x86_64/sysroot
二、下载
1、NDK:
NDK 下载 | Android NDK | Android Developers
https://dl.google.com/android/repository/android-ndk-r21b-linux-x86_64.zip
2、FFmpeg:
https://ffmpeg.org/releases/ffmpeg-4.2.2.tar.bz2
三、生成so库
1、编写脚本
在 ffmpeg-4.2.2 根目录下新建 shell 脚本,命名为: build_android_clang.sh,脚本代码如下:
#!/bin/bash
export NDK=/Users/xxx/Library/Android/sdk/ndk/21.1.6352462 #这里配置先你的 NDK 路径
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64
function build_android
{
./configure \
--prefix=$PREFIX \
--enable-neon \
--enable-hwaccels \
--enable-gpl \
--disable-postproc \
--disable-debug \
--enable-small \
--enable-jni \
--enable-mediacodec \
--enable-decoder=h264_mediacodec \
--enable-static \
--enable-shared \
--disable-doc \
--enable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-avdevice \
--disable-doc \
--disable-symver \
--cross-prefix=$CROSS_PREFIX \
--target-os=android \
--arch=$ARCH \
--cpu=$CPU \
--cc=$CC \
--cxx=$CXX \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $OPTIMIZE_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS"
make clean
make -j16
make install
echo "============================ build android arm64-v8a success =========================="
}
#arm64-v8a
ARCH=arm64
CPU=armv8-a
API=21
CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
SYSROOT=$NDK/toolchains/llvm/prebuilt/darwin-x86_64/sysroot
CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-
PREFIX=$(dirname $(pwd))/so/$CPU
OPTIMIZE_CFLAGS="-march=$CPU"
build_android
这两个地方那个需要修改为自己的:
export NDK:NDK的本地路径。
PREFIX:文件输出路径。
2、使脚本生效
chmod +x build_android_clang.sh
3、执行脚本
./build_android_clang.sh
大概三五分钟分钟得到结果如下:
.so:表示动态库
.a: 表示生成的静态库
二者的都可以使用,想用哪个拷贝哪个。
生成的文件下载地址:ffmpeg-armv8-a.zip_-编解码文档类资源-CSDN下载
# Linxu编译
1、下载ffmpeg和NDK并解压
wget http://ffmpeg.org/releases/ffmpeg-4.2.5.tar.gz
wget https://dl.google.com/android/repository/android-ndk-r21b-linux-x86_64.zip
2、配置环境变量
vi /etc/profile
export NDKROOT=/home/ubuntu/ndk/android-ndk-r21b
export PATH=$NDKROOT:$PATH
source /etc/profile
3、配置脚本android_build.sh
#!/bin/bash
# ndk路径
NDK=/home/ubuntu/ndk/android-ndk-r21b
# 编译工具链目录,ndk17版本以上用的是clang,以下是gcc
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
# 版本号
API=21
# 交叉编译树的根目录(查找相应头文件和库用)
SYSROOT="${TOOLCHAIN}/sysroot"
# 定义执行configure的shell方法
function build_android() {
./ffmpeg-4.2.5/configure \
--prefix=$PREFIX \
--enable-shared \
--disable-static \
--enable-jni \
--enable-gpl \
--enable-small \
--disable-doc \
--disable-programs \
--disable-symver \
--target-os=android \
--arch=$ARCH \
--cpu=$CPU \
--cc=$CC \
--cxx=$CXX \
--enable-cross-compile \
--cross-prefix=$CROSS_COMPILE \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $OPTIMIZE_CFLAGS" \
--extra-ldflags="" \
--disable-asm \
$COMMON_FF_CFG_FLAGS
make clean
make -j16
make install
}
# arm
OUTPUT_FOLDER=armv7-a
ARCH=arm
CPU=armv7-a
TOOL_CPU_NAME=armv7a
TOOL_PREFIX=$TOOLCHAIN/bin/${TOOL_CPU_NAME}-linux-androideabi
OPTIMIZE_CFLAGS="-marm -march=$CPU"
PREFIX=${PWD}/android/$OUTPUT_FOLDER
CROSS_COMPILE=$TOOLCHAIN/bin/arm-linux-androideabi-
CC=${TOOL_PREFIX}${API}-clang
CXX=${TOOL_PREFIX}${API}-clang++
build_android
# arm64,这个指令集最低支持api21
OUTPUT_FOLDER=arm64-v8a
ARCH=aarch64
CPU=armv8-a
TOOL_CPU_NAME=aarch64
TOOL_PREFIX=$TOOLCHAIN/bin/${TOOL_CPU_NAME}-linux-android
OPTIMIZE_CFLAGS="-march=$CPU"
PREFIX=${PWD}/android/$OUTPUT_FOLDER
CROSS_COMPILE=$TOOLCHAIN/bin/aarch64-linux-android-
CC=${TOOL_PREFIX}${API}-clang
CXX=${TOOL_PREFIX}${API}-clang++
build_android
# x86
OUTPUT_FOLDER=x86
ARCH=x86
CPU=x86
TOOL_CPU_NAME=i686
TOOL_PREFIX=$TOOLCHAIN/bin/${TOOL_CPU_NAME}-linux-android
OPTIMIZE_CFLAGS="-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32"
PREFIX=${PWD}/android/$OUTPUT_FOLDER
CROSS_COMPILE=$TOOLCHAIN/bin/i686-linux-android-
CC=${TOOL_PREFIX}${API}-clang
CXX=${TOOL_PREFIX}${API}-clang++
build_android
# x86_64,这个指令集最低支持api21
OUTPUT_FOLDER=x86_64
ARCH=x86_64
CPU=x86-64
TOOL_CPU_NAME=x86_64
TOOL_PREFIX=$TOOLCHAIN/bin/${TOOL_CPU_NAME}-linux-android
OPTIMIZE_CFLAGS="-march=$CPU -mtune=intel -msse4.2 -mpopcnt -m64"
# 输出目录
PREFIX=${PWD}/android/$OUTPUT_FOLDER
CROSS_COMPILE=$TOOLCHAIN/bin/x86_64-linux-android-
# so的输出目录, --libdir=$LIB_DIR 可以不用指定,默认会生成在$PREFIX/lib目录中
#LIB_DIR="${PWD}/android/libs/$OUTPUT_FOLDER"
# 编译器
CC=${TOOL_PREFIX}${API}-clang
CXX=${TOOL_PREFIX}${API}-clang++
build_android
4、运行脚本
./android_build.sh
经过对比,linxu速度更快,几分钟就编译生成了。
下篇文章介绍如何集成:FFmpeg集成