2019 最新 Android 平台 ffmpeg 4.1.3 编译流程 集成x264编码库 生成so文件

注意:此方法在windows平台上使用MSYS环境不可行。并且NDK版本变化快,仅供参考

改良自博客 原文 毛毛v5 ffmpeg android ndk编译,还是用的gcc,不会配置clang版的
编译环境

1 Ubuntu 64位(2020/5/19更新:windows环境下,安装自带linux子系统 ubuntu测试成功)
2 NDK r19c
3 FFmpeg 4.1.3 源码 (可以不提前下载,2020/5/19更新:4.2.2版本测试成功)
4 x264源码(可以不提前下载,2020/5/19更新:最新版本测试成功)

最近在从源码编译视频框架,但网上很多脚本都是两三年前的,不适用于最近的版本ffmpeg ,或者只针对特定cpu架构的。

编译过程 ,整个过程就编辑3个脚本文件即可。
1 下载NDK r19c (我试过 其他版本的NDK,无法完成整个过程)

1 编辑 安卓NDK工具链脚本。找一个目录 终端进入 键入 touch make_android_toolchain.sh ,创建一个脚本。文本编辑器进行编辑 输入下面的内容

#!/bin/bash
#NDK目录,你要改成自己的ndk解压缩后所在的目录
export NDK_HOME=/home/akbot/Android/android-ndk-r19c
#生成交叉编译链工具
toolchain=${NDK_HOME}/build/tools/make-standalone-toolchain.sh
#生成交叉编译链保存在当前目录子文件夹android-toolchain
install_root=`pwd`/android-toolchain-r19

#生成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

这个脚本是使用NDK自带的工具链生成工具生成编译所需要的命令行工具集,真正做编译链接流程。

2 接着在相同文件夹下创建第二个脚本,编译x264库。终端打开当前目录 输入 touch android_build_x264.sh 创建脚本 ,用文本编辑器打开

#!/bin/bash

ROOT=`pwd`/
#配置交叉编译链,未生成交叉编译链请参考https://github.com/cwj2014/android_toolchain
export TOOL_ROOT=$ROOT/android-toolchain-r19
#五种类型cpu编译链
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__"
   "-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

这个脚本会生成针对
“armeabi”
“armeabi-v7a”
“arm64-v8a”
“x86”
“x86_64”
这些架构的cpu的 x264动态库,为后续的ffmpeg编译依赖,可以根据需要缩减
脚本中判断了当前目录是否有x264源码 ,如果没有会自动下载完进行编译。

3 创建最后一个脚本 编译最终的ffmpeg动态库 。
在与上面相同的目录,打开终端 输入 touch android_build_ffmpeg.sh,用文本编辑器打开 ,输入下面内容

#!/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-r19
#五种类型cpu编译链
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"
    
   #交叉编译最重要的是配置--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

这个脚本会生成针对
“armeabi”
“armeabi-v7a”
“arm64-v8a”
“x86”
“x86_64”
这些架构的cpu的 ffmpeg动态库,可以根据需要缩减
脚本中判断了当前目录是否有FFmpeg 4.1.3源码 ,如果没有会自动下载完进行编译。

如果没有提前下载源码,则当前目录只有三个脚本文件在这里插入图片描述
4 执行编译
(可选) 可能需要首先给这些脚本执行权限
终端打开当前目录 分别输入
chmod +x make_android_toolchain.sh
chmod +x android_build_x264.sh
chmod +x android_build_ffmpeg.sh

然后分别执行1 2 3 三个脚本

终端进入当前目录
依此执行

./make_android_toolchain.sh

这一步如果报

ERROR: Failed to create toolchain

可能没有最新版python 请用

apt-get install python

安装 python

接下来

./android_build_x264.sh

这一步用到了git,如果没有安装可能会报错,可以输入

sudo apt install git

进行安装,不过也可以不用,如果提前下载了x264源码并放在了x264命名的目录下的话,下面ffmpeg脚本一个道理

最后

./android_build_ffmpeg.sh

后两个耗时较长,需要耐心等待 。

执行完毕后 ,ffmpeg 编译好的内容会在 ffmpeg-install目录下

2019 最新 Android 平台 ffmpeg 4.1.3 编译流程 集成x264编码库 生成so文件_第1张图片
如果没有问题 你们的目录下应该与我的是一样的 ,除了android-toolchain-r15,r10,r17没有 (这三个toolchain是我自己额外生成的,没有用到)

进入 ffmpeg-install —> armeabi/armeabi-v7a/arm64-v8a/x86 —> lib 目录 就能看到编译好的动态链接库文件了
2019 最新 Android 平台 ffmpeg 4.1.3 编译流程 集成x264编码库 生成so文件_第2张图片

就能集成进AndroidStudio进行后续开发了。
下一篇将会介绍把编译好的动态库放入android工程,实现视频播放功能。

如果有疑问,请在下方留言。如果有帮助可以点一个赞哦。

参考资料
参考资料

后记:

1 后面引入到Android工程时,运行报错,类似 找不到 libx264.so.xxx

为了后续方便,需要在源码目录中修改两个config文件

首先,进入ffmpeg-4.1.3目录 文本编辑器打开编辑目录下面的 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目录 ,同样用文本编辑器打开 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

因为经过上述操作已经编译好了,修改完需要重新执行一遍
chmod +x android_build_x264.sh
chmod +x android_build_ffmpeg.sh

这两个脚本,重新生成库文件。

#2019.8.30 更新
2 ffmpeg和x264编译脚本的 extra_ldflags 配置都增加了 -lc 选项,原因是为了解决后续在android项目中引入时,某些手机运行出现的 “找不到gettimeofday” 的问题。

你可能感兴趣的:(FFmpeg,Android,x264,NDK)