本次编译是MacBookPro macOs14.6.1 (23G93)上进行的。
一 .下载libx264源代码:
libx264的github地址为: https://code.videolan.org/videolan/x264.git
用git下载到本地:
git clone https://code.videolan.org/videolan/x264.git
二.NDK的配置及路径查找:
在这里之前文章已经描述了从android studio下载及查找的路径的方法,这里不再赘述。
感兴趣的可以移步博客:macOs上交叉编译ffmpeg及安装ffmpeg工具_ffmpeg macos-CSDN博客
三.创建编译脚本android_x264.sh :
1.编写编译脚本:
在“一”中git下载的目录路径在创建一个android_x264.sh的脚本:
sudo vim android_x264.sh
加入如下的脚本代码:
#!/bin/bash
# macOS平台下用于android平台NDK为android-ndk-r27c交叉编译X264的脚本
# NDK所在目录
export NDK=/Users/wangyao/Library/Android/sdk/ndk/25.1.8937393 # tag1
export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64
export SYSROOT=$NDK/toolchains/llvm/prebuilt/darwin-x86_64/sysroot
export ANDROID_API=24
export AR=$TOOLCHAIN/bin/llvm-ar
export LD=$TOOLCHAIN/bin/ld
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
export STRIP=$TOOLCHAIN/bin/llvm-strip
export NM=$TOOLCHAIN/bin/llvm-nm
#export STRINGS=$TOOLCHAIN/llvm-strings
build_armv7(){
echo "-------- > Start install build_armv7"
export CC=$TOOLCHAIN/bin/armv7a-linux-androideabi$ANDROID_API-clang
export CXX=$TOOLCHAIN/bin/armv7a-linux-androideabi$ANDROID_API-clang++
#编译选项
EXTRA_CFLAGS="-march=armv7-a -D__ANDROID__"
PREFIX=`pwd`/android/arm-v7a
# 配置和编译
./configure \
--host=armv7a-linux-androideabi \
--sysroot=${SYSROOT} \
--prefix=${PREFIX} \
--enable-shared \
--enable-static \
--disable-asm \
--chroma-format=all \
--enable-pic \
--enable-strip \
--disable-cli \
--disable-win32thread \
--disable-avs \
--disable-swscale \
--disable-lavf \
--disable-ffms \
--disable-gpac \
--disable-lsmash \
--extra-cflags="-Os -fpic ${EXTRA_CFLAGS}" \
--extra-ldflags="" \
make clean
make -j4
make install
}
build_armv8(){
echo "-------- > Start install build_armv8"
export CC=$TOOLCHAIN/bin/aarch64-linux-android$ANDROID_API-clang
export CXX=$TOOLCHAIN/bin/aarch64-linux-android$ANDROID_API-clang++
#编译选项
EXTRA_CFLAGS="-march=armv8-a -D__ANDROID__"
PREFIX=`pwd`/android/arm64-v8a
# 配置和编译
./configure \
--host=aarch64-linux-android \
--sysroot=${SYSROOT} \
--prefix=${PREFIX} \
--enable-shared \
--enable-static \
--disable-asm \
--chroma-format=all \
--enable-pic \
--enable-strip \
--disable-cli \
--disable-win32thread \
--disable-avs \
--disable-swscale \
--disable-lavf \
--disable-ffms \
--disable-gpac \
--disable-lsmash \
--extra-cflags="-Os -fpic ${EXTRA_CFLAGS}" \
--extra-ldflags="" \
make clean
make -j4
make install
}
build_x86(){
echo "-------- > Start install build_x86"
export CC=$TOOLCHAIN/bin/i686-linux-android$ANDROID_API-clang
export CXX=$TOOLCHAIN/bin/i686-linux-android$ANDROID_API-clang++
#编译选项
EXTRA_CFLAGS="-D__ANDROID__"
PREFIX=`pwd`/android/x86
# 配置和编译
./configure \
--host=i686-linux-android \
--sysroot=${SYSROOT} \
--prefix=${PREFIX} \
--enable-shared \
--enable-static \
--chroma-format=all \
--disable-asm \
--enable-pic \
--enable-strip \
--disable-cli \
--disable-win32thread \
--disable-avs \
--disable-swscale \
--disable-lavf \
--disable-ffms \
--disable-gpac \
--disable-lsmash \
--extra-cflags="-Os -fpic ${EXTRA_CFLAGS}" \
--extra-ldflags="" \
make clean
make -j4
make install
}
build_x86_64(){
echo "-------- > Start install build_x86_64"
export CC=$TOOLCHAIN/bin/x86_64-linux-android$ANDROID_API-clang
export CXX=$TOOLCHAIN/bin/x86_64-linux-android$ANDROID_API-clang++
#编译选项
EXTRA_CFLAGS="-D__ANDROID__"
PREFIX=`pwd`/android/x86_64
# 配置和编译
./configure \
--host=x86_64-linux-android \
--sysroot=${SYSROOT} \
--prefix=${PREFIX} \
--enable-shared \
--enable-static \
--disable-asm \
--chroma-format=all \
--enable-pic \
--enable-strip \
--disable-cli \
--disable-win32thread \
--disable-avs \
--disable-swscale \
--disable-lavf \
--disable-ffms \
--disable-gpac \
--disable-lsmash \
--extra-cflags="-Os -fpic ${EXTRA_CFLAGS}" \
--extra-ldflags="" \
make clean
make -j4
make install
}
build_armv7
build_armv8
build_x86
build_x86_64
2.运行编译脚本:
sudo sh android_x264.sh
3.编译结果:
编译完成后会生成arm-v7/arm64-v8a/x86/x86_64的结果:
include中包含x264_config.h及x264.h的头文件
lib中包含libx264.a/libx264.so/libx264.so.165的动态库,及pkgconfig。
pkgconfig文件夹下包含一个x264.pc的配置文件,用于后面ffmpeg编译时传递给configure。内部链接时查找对应libx264头文件及库的配置。
x264.pc的内容如下:
prefix=/Users/wangyao/ffmpeg/x264/x264/android/arm-v7a
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: x264
Description: H.264 (MPEG4 AVC) encoder library
Version: 0.165.3222
Libs: -L${exec_prefix}/lib -lx264
Libs.private: -lm -ldl
Cflags: -I${prefix}/include -DX264_API_IMPORTS
4.坑:
虽然编译出了上述的编译结果,但后面把libx264加入ffmpeg交叉编译时。会有一个巨坑,就是libx264动态库的链接是链接到“libx264.so.165”而不是链接到“libx264.so”。
在android的动态库的链接时会报错“dlopen failed: library "libx264.so.165" not found”
这就需要解决libx264库编译的问题:
在x264的configure中把查找到“libx264.so.$API”替换成“libx264.so”。
替换后在重新编译,完成的结果就不包含“libx264.so.165”:
四.FFmpeg加入libx264的编译:
1.查找x264的编译结果目录路径:
查找x264的编译结果include/lib及pkgconfig目录路径
2.在ffmpeg的目录下创建android_ff_x264.sh脚本:
加入如下的脚本代码:
#!/bin/bash
# 用于编译android平台的脚本
# NDK所在目录
NDK_PATH=/Users/wangyao/Library/Android/sdk/ndk/25.1.8937393 # tag1
# 主机平台
HOST_PLATFORM=darwin-x86_64
# minSdkVersion
API=24 # 提高到 API 24 以避免 fseeko64/ftello64 问题
TOOLCHAINS="$NDK_PATH/toolchains/llvm/prebuilt/$HOST_PLATFORM"
SYSROOT="$NDK_PATH/toolchains/llvm/prebuilt/$HOST_PLATFORM/sysroot"
# 生成 -fpic 与位置无关的代码
CFLAG="-D__ANDROID_API__=$API -Os -fPIC -DANDROID -D_FILE_OFFSET_BITS=64"
LDFLAG="-lc -lm -ldl -llog "
# 输出目录
PREFIX=$(pwd)/android
# 日志输出目录
CONFIG_LOG_PATH=${PREFIX}/log
# 公共配置
COMMON_OPTIONS=
# 交叉配置
CONFIGURATION=
# 创建必要的目录
mkdir -p ${PREFIX} ${CONFIG_LOG_PATH}
build() {
APP_ABI=$1
echo "======== > Start build $APP_ABI"
# 重置变量
EXTRA_CFLAGS="$CFLAG"
EXTRA_LDFLAGS="$LDFLAG"
EXTRA_OPTIONS=""
PKG_CONFIG_AVAILABLE=false
case ${APP_ABI} in
armeabi-v7a)
ARCH="arm"
CPU="armv7-a"
MARCH="armv7-a"
TARGET=armv7a-linux-androideabi
CC="$TOOLCHAINS/bin/$TARGET$API-clang"
CXX="$TOOLCHAINS/bin/$TARGET$API-clang++"
LD="$TOOLCHAINS/bin/$TARGET$API-clang"
# 交叉编译工具前缀
CROSS_PREFIX="$TOOLCHAINS/bin/arm-linux-androideabi-"
# 设置pkg-config路径
export PKG_CONFIG_PATH="/Users/wangyao/ffmpeg/x264/x264/android/arm-v7a/lib/pkgconfig"
echo "-------- > PKG_CONFIG_PATH=$PKG_CONFIG_PATH"
# 指定X264的库
X264_INCLUDE="/Users/wangyao/ffmpeg/x264/x264/android/arm-v7a/include"
X264_LIB="/Users/wangyao/ffmpeg/x264/x264/android/arm-v7a/lib"
echo "-------- > X264_INCLUDE=$X264_INCLUDE"
echo "-------- > X264_LIB=$X264_LIB"
# 检查x264库是否存在
if [ ! -f "$X264_LIB/libx264.so" ]; then
echo "错误: 找不到x264共享库文件在 $X264_LIB"
echo "请先编译x264库或检查路径是否正确"
exit 1
fi
# 检查x264.pc文件是否存在
local x264_pc_file="$X264_LIB/pkgconfig/x264.pc"
if [ -f "$x264_pc_file" ]; then
echo "-------- > x264.pc found"
# 尝试使用pkg-config获取正确的编译标志
if pkg-config --exists x264; then
X264_CFLAGS=$(pkg-config --cflags x264)
X264_LIBS=$(pkg-config --libs x264)
echo "-------- > pkg-config found x264 successfully"
echo "-------- > x264 CFLAGS: $X264_CFLAGS"
echo "-------- > x264 LIBS: $X264_LIBS"
EXTRA_CFLAGS="$EXTRA_CFLAGS $X264_CFLAGS"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS $X264_LIBS"
PKG_CONFIG_AVAILABLE=true
else
echo "-------- > WARNING: pkg-config cannot find x264, using manual flags"
EXTRA_CFLAGS="$EXTRA_CFLAGS -I$X264_INCLUDE"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -L$X264_LIB -lx264"
fi
else
echo "-------- > WARNING: x264.pc not found, using manual flags"
EXTRA_CFLAGS="$EXTRA_CFLAGS -I$X264_INCLUDE"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -L$X264_LIB -lx264"
fi
# 添加架构特定标志
EXTRA_CFLAGS="$EXTRA_CFLAGS -mfloat-abi=softfp -mfpu=neon -marm -march=$MARCH"
EXTRA_OPTIONS="--enable-neon --cpu=$CPU"
;;
arm64-v8a)
ARCH="aarch64"
CPU="armv8-a"
TARGET=aarch64-linux-android
CC="$TOOLCHAINS/bin/$TARGET$API-clang"
CXX="$TOOLCHAINS/bin/$TARGET$API-clang++"
LD="$TOOLCHAINS/bin/$TARGET$API-clang"
CROSS_PREFIX="$TOOLCHAINS/bin/aarch64-linux-android-"
# 设置pkg-config路径
export PKG_CONFIG_PATH="/Users/wangyao/ffmpeg/x264/x264/android/arm64-v8a/lib/pkgconfig"
# 指定X264的库
X264_INCLUDE="/Users/wangyao/ffmpeg/x264/x264/android/arm64-v8a/include"
X264_LIB="/Users/wangyao/ffmpeg/x264/x264/android/arm64-v8a/lib"
# 检查x264库是否存在
if [ ! -f "$X264_LIB/libx264.so" ]; then
echo "错误: 找不到x264共享库文件在 $X264_LIB"
exit 1
fi
# 手动添加x264标志
EXTRA_CFLAGS="$EXTRA_CFLAGS -I$X264_INCLUDE"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -L$X264_LIB -lx264"
;;
x86)
ARCH="x86"
CPU="i686"
TARGET=i686-linux-android
CC="$TOOLCHAINS/bin/$TARGET$API-clang"
CXX="$TOOLCHAINS/bin/$TARGET$API-clang++"
LD="$TOOLCHAINS/bin/$TARGET$API-clang"
CROSS_PREFIX="$TOOLCHAINS/bin/i686-linux-android-"
# 禁用不支持的选项
EXTRA_OPTIONS="--disable-neon --disable-asm"
;;
x86_64)
ARCH="x86_64"
CPU="x86_64"
TARGET=x86_64-linux-android
CC="$TOOLCHAINS/bin/$TARGET$API-clang"
CXX="$TOOLCHAINS/bin/$TARGET$API-clang++"
LD="$TOOLCHAINS/bin/$TARGET$API-clang"
CROSS_PREFIX="$TOOLCHAINS/bin/x86_64-linux-android-"
# 禁用不支持的选项
EXTRA_OPTIONS="--disable-neon"
;;
esac
echo "-------- > Start clean workspace"
make clean > /dev/null 2>&1
echo "-------- > Start build configuration"
CONFIGURATION="$COMMON_OPTIONS"
CONFIGURATION="$CONFIGURATION --logfile=$CONFIG_LOG_PATH/config_$APP_ABI.log"
CONFIGURATION="$CONFIGURATION --prefix=$PREFIX"
CONFIGURATION="$CONFIGURATION --libdir=$PREFIX/libs/$APP_ABI"
CONFIGURATION="$CONFIGURATION --incdir=$PREFIX/includes/$APP_ABI"
CONFIGURATION="$CONFIGURATION --pkgconfigdir=$PREFIX/pkgconfig/$APP_ABI"
CONFIGURATION="$CONFIGURATION --cross-prefix=$CROSS_PREFIX"
CONFIGURATION="$CONFIGURATION --arch=$ARCH"
CONFIGURATION="$CONFIGURATION --sysroot=$SYSROOT"
CONFIGURATION="$CONFIGURATION --cc=$CC"
CONFIGURATION="$CONFIGURATION --cxx=$CXX"
CONFIGURATION="$CONFIGURATION --ld=$LD"
#libx264
CONFIGURATION="$CONFIGURATION --enable-libx264"
CONFIGURATION="$CONFIGURATION --enable-encoder=libx264"
# nm 和 strip
CONFIGURATION="$CONFIGURATION --nm=$TOOLCHAINS/bin/llvm-nm"
CONFIGURATION="$CONFIGURATION --strip=$TOOLCHAINS/bin/llvm-strip"
CONFIGURATION="$CONFIGURATION $EXTRA_OPTIONS"
echo "-------- > Start config makefile with $CONFIGURATION"
echo "-------- > Extra CFLAGS: $EXTRA_CFLAGS"
echo "-------- > Extra LDFLAGS: $EXTRA_LDFLAGS"
./configure ${CONFIGURATION} \
--extra-cflags="$EXTRA_CFLAGS" \
--extra-ldflags="$EXTRA_LDFLAGS" \
--pkg-config=$(which pkg-config) 2>&1 | tee $CONFIG_LOG_PATH/configure_$APP_ABI.log
echo "-------- > Start make $APP_ABI with -j4"
make -j4
echo "-------- > Start install $APP_ABI"
make install
echo "++++++++ > make and install $APP_ABI complete."
return 0
}
build_all() {
#配置开源协议声明
COMMON_OPTIONS="$COMMON_OPTIONS --enable-gpl"
#目标android平台
COMMON_OPTIONS="$COMMON_OPTIONS --target-os=android"
#取消默认的静态库
COMMON_OPTIONS="$COMMON_OPTIONS --disable-static"
COMMON_OPTIONS="$COMMON_OPTIONS --enable-shared"
COMMON_OPTIONS="$COMMON_OPTIONS --enable-protocols"
#开启交叉编译
COMMON_OPTIONS="$COMMON_OPTIONS --enable-cross-compile"
COMMON_OPTIONS="$COMMON_OPTIONS --enable-optimizations"
COMMON_OPTIONS="$COMMON_OPTIONS --disable-debug"
#尽可能小
COMMON_OPTIONS="$COMMON_OPTIONS --enable-small"
COMMON_OPTIONS="$COMMON_OPTIONS --disable-doc"
#不要命令(执行文件)
COMMON_OPTIONS="$COMMON_OPTIONS --disable-programs" # do not build command line programs
COMMON_OPTIONS="$COMMON_OPTIONS --disable-ffmpeg" # disable ffmpeg build
COMMON_OPTIONS="$COMMON_OPTIONS --disable-ffplay" # disable ffplay build
COMMON_OPTIONS="$COMMON_OPTIONS --disable-ffprobe" # disable ffprobe build
COMMON_OPTIONS="$COMMON_OPTIONS --disable-symver"
COMMON_OPTIONS="$COMMON_OPTIONS --disable-network"
COMMON_OPTIONS="$COMMON_OPTIONS --disable-x86asm"
COMMON_OPTIONS="$COMMON_OPTIONS --disable-vulkan"
# 有条件地禁用asm,某些架构可能不支持
COMMON_OPTIONS="$COMMON_OPTIONS --disable-asm"
#启用
COMMON_OPTIONS="$COMMON_OPTIONS --enable-pthreads"
COMMON_OPTIONS="$COMMON_OPTIONS --enable-mediacodec"
COMMON_OPTIONS="$COMMON_OPTIONS --enable-jni"
COMMON_OPTIONS="$COMMON_OPTIONS --enable-zlib"
COMMON_OPTIONS="$COMMON_OPTIONS --enable-pic"
COMMON_OPTIONS="$COMMON_OPTIONS --enable-muxer=flv"
COMMON_OPTIONS="$COMMON_OPTIONS --enable-decoder=h264"
COMMON_OPTIONS="$COMMON_OPTIONS --enable-decoder=mpeg4"
COMMON_OPTIONS="$COMMON_OPTIONS --enable-decoder=mjpeg"
COMMON_OPTIONS="$COMMON_OPTIONS --enable-decoder=png"
COMMON_OPTIONS="$COMMON_OPTIONS --enable-decoder=vorbis"
COMMON_OPTIONS="$COMMON_OPTIONS --enable-decoder=opus"
COMMON_OPTIONS="$COMMON_OPTIONS --enable-decoder=flac"
#启用编码器
COMMON_OPTIONS="$COMMON_OPTIONS --enable-encoder=h264"
#libx264
COMMON_OPTIONS="$COMMON_OPTIONS --enable-libx264"
COMMON_OPTIONS="$COMMON_OPTIONS --enable-encoder=libx264"
echo "COMMON_OPTIONS=$COMMON_OPTIONS"
echo "PREFIX=$PREFIX"
echo "CONFIG_LOG_PATH=$CONFIG_LOG_PATH"
# 构建所有支持的架构
build "armeabi-v7a" || echo "Failed to build armeabi-v7a"
build "arm64-v8a" || echo "Failed to build arm64-v8a"
# build "x86" || echo "Failed to build x86"
# build "x86_64" || echo "Failed to build x86_64"
}
echo "-------- Start --------"
build_all
echo "-------- End --------"
3.编译android_ff_x264.sh脚本:
4.编译结果:
在“/Users/wangyao/ffmpeg/ffmpeg-7.0.2/android”目录下即是编译的结果了: