android linux编译FFmpeg 和 x264框架so库
在学习编译X264的时候找了很多资料都没有编译成功,这里记录一下编译成功的脚本
参考资料点击这里
编译步骤:
- 使用NDK生成编译所需要的命令工具集
- 编译X264框架
- 编译FFmpeg,并加上x264
一、生成命令工具集
找个新的目录新建一个编译脚本文件,例如:vim make_android_toolchain.sh 把下面编辑脚本复制进去(注意要修改NDK目录)
#!/bin/bash
#NDK目录,你要改成自己的ndk解压缩后所在的目录
export NDK_HOME=/home/mirrer/work/ffmpeg/android-ndk-r21e
#生成交叉编译链工具
toolchain=${NDK_HOME}/build/tools/make-standalone-toolchain.sh
#生成交叉编译链保存在当前目录子文件夹android-toolchain
install_root=`pwd`/android-toolchain-r21
#生成32位库最低支持到android4.3,64位库最低支持到android5.0
platforms=(
"android-18"
"android-18"
"android-21"
"android-18"
"android-21"
)
#支持以下5种cpu框架
archs=(
"arm"
"arm"
"arm64"
"x86"
"x86_64"
)
#cpu型号
abis=(
"armeabi"
"armeabi-v7a"
"arm64-v8a"
"x86"
"x86_64"
)
echo $NDK_HOME
echo "安装在目录:$install_root"
num=${#abis[@]}
for ((i=0; i<num; i++))
do
bash $toolchain --arch=${archs[i]} --platform=${platforms[i]} --abis=${abis[i]} --install-dir=$install_root/${abis[i]}
done
脚本编译完成后会在目录下生成一个android-toolchain-r21目录
2、编译X264库
同样在当前目录下新建一个编译脚本文件,例如:vim android_build_x264.sh 把以下脚本代码复制进去
#!/bin/bash
ROOT=`pwd`/
#配置交叉编译链,未生成交叉编译链请参考https://github.com/cwj2014/android_toolchain
export TOOL_ROOT=$ROOT/android-toolchain-r21
#五种类型cpu编译链 这里我注释了几个 想编译x86架构的把注释打开就行
android_toolchains=(
"armeabi"
"armeabi-v7a"
#"arm64-v8a"
#"x86"
#"x86_64"
)
#优化编译项
extra_cflags=(
"-march=armv5te -msoft-float -D__ANDROID__ -D__ARM_ARCH_5TE__ -D__ARM_ARCH_5TEJ__"
"-march=armv7-a -mfloat-abi=softfp -mfpu=neon -mthumb -D__ANDROID__ -D__ARM_ARCH_7__ -D__ARM_ARCH_7A__ -D__ARM_ARCH_7R__ -D__ARM_ARCH_7M__ -D__ARM_ARCH_7S__ -Wl,--exclude-libs,libgcc_real.a"
"-march=armv8-a -D__ANDROID__ -D__ARM_ARCH_8__ -D__ARM_ARCH_8A__"
"-march=i686 -mtune=i686 -m32 -mmmx -msse2 -msse3 -mssse3 -D__ANDROID__ -D__i686__"
"-march=core-avx-i -mtune=core-avx-i -m64 -mmmx -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -mpopcnt -D__ANDROID__ -D__x86_64__"
)
extra_ldflags="-nostdlib -lc"
#共同配置项,可以额外增加相关配置,详情可查看源文件目录下configure
configure="--disable-cli \
--enable-static \
--enable-shared \
--disable-opencl \
--enable-strip \
--disable-cli \
--disable-win32thread \
--disable-avs \
--disable-swscale \
--disable-lavf \
--disable-ffms \
--disable-gpac \
--disable-lsmash"
#针对各版本不同的编译项
extra_configure=(
"--disable-asm"
""
""
"--disable-asm"
"--disable-asm"
)
#交叉编译后的运行环境
hosts=(
"arm-linux-androideabi"
"arm-linux-androideabi"
"aarch64-linux-android"
"i686-linux-android"
"x86_64-linux-android"
)
#交叉编译工具前缀
cross_prefix=(
"arm-linux-androideabi-"
"arm-linux-androideabi-"
"aarch64-linux-android-"
"i686-linux-android-"
"x86_64-linux-android-"
)
#当前目录下x264源文件目录
if [ ! -d "x264" ]
then
echo "下载x264源文件"
git clone https://code.videolan.org/videolan/x264.git
fi
SOURCE=x264
#安装文件夹
INSTALL_DIR="x264_install"
#安装路径,默认安装在当前执行目录下的${INSTALL_DIR}
PREFIX=$ROOT/$INSTALL_DIR
n=${#android_toolchains[@]}
cd $ROOT/$SOURCE
for((i=0; i<n; i++))
do
export PATH=$TOOL_ROOT/${android_toolchains[i]}/bin:$PATH
echo "开始配置${android_toolchains[i]}版本"
#交叉编译最重要的是配置--host、--cross-prefix、sysroot、以及extra-cflags和extra-ldflags
./configure ${configure} \
${extra_configure[i]} \
--prefix=$PREFIX/${android_toolchains[i]} \
--host=${hosts[i]} \
--cross-prefix=${cross_prefix[i]} \
--sysroot=$TOOL_ROOT/${android_toolchains[i]}/sysroot \
#--extra-cflags="${extra_cflags[i]}" \ #这里有注释
--extra-ldflags="$extra_ldflags"
make clean
echo "开始编译并安装${android_toolchains[i]}版本"
make -j4 & make install
done
里面的优化编译项被我注释掉了,原因到最后说 #--extra-cflags="${extra_cflags[i]}" 需要的可以自行打开
3、编译FFmpeg
同样在当前目录下新建编译脚本文件,例如:vim android_build_ffmpeg.sh 把以下脚本代码复制进去(注意脚本编译的FFmpeg 4.1.2版本,可以自行修改版本)
#!/bin/bash
ROOT=`pwd`
if [ ! -d "ffmpeg-4.1.3" ]
then
# echo "解压ffmpeg-4.1.3源文件"
wget http://ffmpeg.org/releases/ffmpeg-4.1.3.tar.bz2
tar -xjvf ffmpeg-4.1.3.tar.bz2
fi
#当前目录下x264源文件目录
SOURCE=ffmpeg-4.1.3
#配置交叉编译链,未生成交叉编译链请参考https://github.com/cwj2014/android_toolchain
export TOOL_ROOT=$ROOT/android-toolchain-r21
#五种类型cpu编译链 需要编译x86架构的可以打开注释
android_toolchains=(
"armeabi"
"armeabi-v7a"
# "arm64-v8a"
# "x86"
# "x86_64"
)
#优化编译项
extra_cflags=(
"-std=gnu11 -march=armv5te -msoft-float -D__ANDROID__ -D__ARM_ARCH_5TE__ -D__ARM_ARCH_5TEJ__"
"-std=gnu11 -march=armv7-a -mfloat-abi=softfp -mfpu=neon -mthumb -D__ANDROID__ -D__ARM_ARCH_7__ -D__ARM_ARCH_7A__ -D__ARM_ARCH_7R__ -D__ARM_ARCH_7M__ -D__ARM_ARCH_7S__"
"-std=gnu11 -march=armv8-a -D__ANDROID__ -D__ARM_ARCH_8__ -D__ARM_ARCH_8A__"
"-std=gnu11 -march=i686 -mtune=i686 -m32 -mmmx -msse2 -msse3 -mssse3 -D__ANDROID__ -D__i686__"
"-std=gnu11 -march=core-avx-i -mtune=core-avx-i -m64 -mmmx -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -mpopcnt -D__ANDROID__ -D__x86_64__"
)
#共同配置项,可以额外增加相关配置,详情可查看源文件目录下configure
#--disable-indev=v4l2 #解决libavdevice/v4l2.c:135:9: error: assigning to 'int (*)(int, unsigned long, ...)'
configure="--enable-gpl \
--enable-version3 \
--enable-nonfree \
--enable-static \
--enable-shared \
--enable-small \
--disable-ffmpeg \
--disable-doc \
--disable-htmlpages \
--disable-manpages \
--disable-podpages \
--disable-txtpages \
--disable-indev=v4l2 \
--enable-libx264"
#针对各版本不同的编译项
extra_configure=(
"--disable-asm"
""
""
"--disable-asm"
"--disable-asm"
)
#交叉编译工具前缀
cross_prefix=(
"arm-linux-androideabi-"
"arm-linux-androideabi-"
"aarch64-linux-android-"
"i686-linux-android-"
"x86_64-linux-android-"
)
#支持以下5种cpu框架
archs=(
"arm"
"arm"
"arm64"
"x86"
"x86_64"
)
#安装文件夹
INSTALL_DIR="ffmpeg_install"
#安装路径,默认安装在当前执行目录下的${INSTALL_DIR}
PREFIX=$ROOT/$INSTALL_DIR
#x264安装目录
X264_INSTALL_DIR=$ROOT/"x264_install"
#libmp3lame安装目录
LAME_INSTALL_DIR=$ROOT/"lame_install"
n=${#android_toolchains[@]}
cd $ROOT/$SOURCE
for((i=0; i<n; i++))
do
export PATH=$TOOL_ROOT/${android_toolchains[i]}/bin:$PATH
echo "开始配置${android_toolchains[i]}版本"
#配置额外库头文件和库文件路径
#extra_include="-I$X264_INSTALL_DIR/${android_toolchains[i]}/include -I$LAME_INSTALL_DIR/${android_toolchains[i]}/include"
#extra_lib="-L$X264_INSTALL_DIR/${android_toolchains[i]}/lib -L$LAME_INSTALL_DIR/${android_toolchains[i]}/lib -lc"
extra_include="-I$X264_INSTALL_DIR/${android_toolchains[i]}/include "
extra_lib="-L$X264_INSTALL_DIR/${android_toolchains[i]}/lib -lc"
#交叉编译最重要的是配置--host、--cross-prefix、sysroot、以及extra-cflags和extra-ldflags
./configure ${configure} \
${extra_configure[i]} \
--prefix=$PREFIX/${android_toolchains[i]} \
--enable-cross-compile \
--target-os=android \
--arch=${archs[i]} \
--cross-prefix=${cross_prefix[i]} \
--sysroot=$TOOL_ROOT/${android_toolchains[i]}/sysroot \
--extra-cflags="${extra_cflags[i]} $extra_include" \
--extra-ldflags="$extra_lib"
make clean
echo "开始编译并安装${android_toolchains[i]}版本"
make -j4
make install
done
到此目录下应该有三个脚本文件:
- make_android_toolchain.sh
- android_build_x264.sh
- android_build_ffmpeg.sh
脚本问题没问题的话,现在开始编译
首先把三个脚本增加可以执行权限
chmod +x make_android_toolchain.sh
chmod +x android_build_x264.sh
chmod +x android_build_ffmpeg.sh
然后依次执行三个脚本
./make_android_toolchain.sh
./android_build_x264.sh
./android_build_ffmpeg.sh
编译完成后目录下会生成以下目录,x264_install和ffmpeg_install里面有我们需要的so库和头文件
问题
一、默认编译出来的so库会带有后缀,比如xx.so.154这种格式,这种android无法使用;这里需要修改一下configure文件
1、修改x264的configure文件
==============================================
找到下面内容
elif [ "$SYS" = "SunOS" ]; then
echo "SOSUFFIX=so" >> config.mak
echo "SONAME=libx264.so.$api" >> config.mak
echo "SOFLAGS=-shared -Wl,-h,$(SONAME) $SOFLAGS" >> config.mak
else
echo "SOSUFFIX=so" >> config.mak
echo "SONAME=libx264.so.$api" >> config.mak
echo "SOFLAGS=-shared -Wl,-soname,$(SONAME) $SOFLAGS" >> config.mak
==============================================
修改成:
elif [ "$SYS" = "SunOS" ]; then
echo "SOSUFFIX=so" >> config.mak
echo "SONAME=libx264.so" >> config.mak
echo "SOFLAGS=-shared -Wl,-h,$(SONAME) $SOFLAGS" >> config.mak
else
echo "SOSUFFIX=so" >> config.mak
echo "SONAME=libx264.so" >> config.mak
echo "SOFLAGS=-shared -Wl,-soname,$(SONAME) $SOFLAGS" >> config.mak
2、修改FFmpeg的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)'
二、我在把x264和ffmpeg导入安卓项目运行的时候报以下错误
最后把x264编译的时候优化选项给注释掉之后就可以了,#--extra-cflags="${extra_cflags[i]}" 就是这句代码
按照上面流程编译出的so就可以正常使用,需要注意的是使用X264.so库的时候,需要把x264.so库复制到安卓项目中,我之前以为会在ffmpeg中一起打包过去的,我这边测试是需要手动复制过来才行,不然会报找不到x264.so库的错误。