使用 Windows 编译 ffmpeg Android so
本文讲述了如何使用 Windows 编译 ffmpeg Android so。
聊聊
这边文章主要是个记录,用于记录本人在 Windows 中编译 ffmpeg 的 Android so 的过程中踩到的坑以及详细过程,方便后续回味。能搜到这里来的同学,想必都知道 ffmpeg 是啥了。我就不多介绍了。不懂的可以百度。
开干。
为啥不用 Windows 直接编译 so
**Windows 直接编译 so 是个大坑,尽量别用 Windows 直接编译 ffmpeg。请记住这句话。**下面来讲几点原因:
- Windows 原生编译 so 的文章相比于 Linux 编译来说,着实不算多。本人也在百度上查阅了各种资料。都没能找到一篇让人满意的参考文章(可能是个人能力有限吧)。
- ffmpeg 是在 Linux 上用纯 C 编写的,证据之一就是 ffmpeg 源码中的 configure 文件,这是 Linux 小开发们常用的编译配置方式。这就导致了在 Windows 上编译 ffmpeg,注定会碰一鼻子灰。尤其是 4.X 以上。比如我遇到的无法解决的一个问题:ffmpeg 4.X.X 以上的软链接问题,其会导致的一个错误如下:
ln: failed to create symbolic link 'libavutil.so': No such file or directory
make: *** [ffbuild/library.mak:102: libavutil/libavutil.so] Error 1
clang: error: no such file or directory: 'liba'
make: *** [ffbuild/library.mak:103: libavformat/libavformat.so.58] Error 1
LD libavformat/libavformat.so.58
clang: error: no such file or directory: 'liba'
make: *** [ffbuild/library.mak:103: libavformat/libavformat.so.58] Error 1
如果想要用 Windows 原生编译 so,可以看看下面两个东西:
- 一个大佬:https://blog.csdn.net/luo0xue/article/details/90369426。
- Windows 中的编译安装过程:
- 安装 Linux 的开发环境:cygwin。请不要使用 MinGW,更不要使用 Git Bash,二者缺少了一些 ffmpeg 编译所需要的文件。
- 在 Linux 开发环境中安装 NDK
- 下载 ffmpeg 源码
- 配置编译脚本,进行编译
Windows10 WSL 编译 Android so
从上面我踩过的坑中,我发现了在 Windows10 中,使用 Windows10 提供的 WSL 来编译是最方便的。因为无论是第一个大佬讲的东西,还是我第二个总结的东西,都绕不开一个问题:**在 Windows 环境下编译 ffmpeg 的 Android so,必须搭建 Linux 的开发环境。**就是基于这一点,我确定了,**在 Windows10 下编译 ffmpeg 的 Android so,使用 Windows10 WSL 是最方便的。**下面来详细讲下在 Windows10 WSL 中,如何编译 Android so
开启 WSL
按照以下步骤打开 Windows10 的 WSL。
打开控制面板操作如下:
鼠标右键 —> 个性化 —> 主题 —> 桌面图标设置 —> 勾中控制面板
至此,控制面板图标便出现在了桌面上:
接着就可以打开 WSL 功能了:控制面板 —> 点击程序和功能 —> 启用或关闭 Windows 功能 —> 适用于 Linux 的 Windows 子系统:
然后,就可以去 Microsoft Store 搜索 Ubuntu 了。可以下载 Ubuntu 20.04 LTS 版本:
安装之后,在开始菜单中点击打开,初始化 OK 之后,就可以做下面的操作了。
WSL 安装 NDK
创建目录:
mkdir -p /home/wenchen/android/ndk
进入目录:
cd /home/wenchen/android/ndk
使用 wget 命令下载 NDK:
wget https://dl.google.com/android/repository/android-ndk-r21e-linux-x86_64.zip
下载完成后解压到 ndk-r21e 目录:
unzip android-ndk-r21e-linux-x86_64.zip -d ndk-r21e
解压好之后配置环境变量:
sudo vim /etc/profile
按 i 键编辑,在配置文件末尾增加以下内容:
#android NDK
export ANDROID_NDK="/home/wenchen/android/ndk/ndk-r21e/android-ndk-r21e"
export PATH="$ANDROID_NDK:$PATH"
按 esc 键退出编辑模式,输入 :wq 保存退出。接着更新环境变量:
source /etc/profile
NDK 就配置好了,接着我们可以看下是否 OK。输入 ndk-build 命令,如果出现以下提示,就 OK 了:
wenchen@DESKTOP-RKNC9R1:~$ ndk-build
Android NDK: Could not find application project directory !
Android NDK: Please define the NDK_PROJECT_PATH variable to point to it.
/home/wenchen/android/ndk/ndk-r21e/android-ndk-r21e/build/core/build-local.mk:151: *** Android NDK: Aborting . Stop.
搭建 Git 开发环境
下载的 Ubuntu 已经为我们装好了 Git,我们只需要配置一下就可以了。
输入下面的命令,配置名称:
git config --global user.name "xxx"
输入下面的命令,配置邮件:
git config --global user.email "xxx@yyy.com"
生成 ssh key pair 密钥对:
启用 ssh-agent:
eval `ssh-agent`
输入以下命令,生成 rsa 密钥。一路回车,不要输入任何东西,直到生成 OK:
ssh-keygen -t rsa -C "注释内容(可以是邮箱地址)"
把私钥添加到 ssh-agent 的高速缓存中:
ssh-add ~/.ssh/id_rsa
打印 rsa 的公钥信息:
cat ~/.ssh/id_rsa.pub
公钥信息如下:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDT+zQtc3Hh/zGKtC7Onx1f256g6JMhdXRBTC4uF7MEzd0zzmic71knFxSKln0xWBmwECUzoQ0FI6dvNGOo8qZfnILjm6WpQDU23wSjGHcEw6CANi3TqRKrFpHU/cY7RzwjVtxMeT5RYaBJ3FsifIYY94s47iYBnEMIu5pdDV9sM0J9sg0TUiZhvwi9y51CL+Vu38kQAQQLlbu27MqJJjHSj6nRis71+b8q0HScp8jlXCuQT/34NMoyXC2pNKHvXOsPGgeU+yoT1K+n2zMvhcSn8F22kDMLpe9kdsBCbwZ0rSylh9wZrTZyGJmCwFm4OP5e0fasofM14EMqK2DtKWTXqyjCSHRilUmuiGFG7SHULeU72Rhu1MutozBfuCDYVI1YlanWrX/ifHtkaI1tlhMXXOISgpbSVP3n5AnGhZ6W1tfp+kNeVGbtYRC/DtmVanUS+T3rr2kWVyGEhEetFZNX1n2ZPRA1+YfICbh2rU9EeumhV1P3BPEF+JWGd8IJszBSvBN/eosys/7KCVyAbOGkeTsWdizJoQN7ArKlnyWSGlIVHaLmyupe/otrfVsFbUd7lF4aPYmLJi4YztSGTBlW1scydnaevi3j5mqgFImALJg6X5KAVnSFVHnYVfIpSdgc5KgcG1wLcTz0lg83ieyhSwFBYykAklRCSjicBOwNrQ== xxx@yyy.com
将公钥信息添加到 Gitee
打开 Gitee 后,选择设置项:
选择 SSH公钥 设置项,粘贴刚才打印的公钥信息,并点击确定,公钥就保存成功了。
下载 ffmpeg 源码
进入目录:
cd /home/wenchen/android
创建源码目录:
mkdir src
创建 so 目录:
mkdir so
进入源码目录:
cd src
下载 ffmpeg 源码:
git clone https://gitee.com/mirrors/ffmpeg.git
下载 OK 后,进入 ffmpeg 源码目录:
cd ffmpeg
修改 configure 文件权限:
chmod 777 configure
在 configure 文件中修改编译脚本设置,新增编译工具拼接选项(ndk 中交叉编译工具名称不同,默认规则拼接后,会出现找不到的情况,解释如图):
打开 Vim:
sudo vim configure
输入 /CMDLINE_SET,按下回车键来匹配设置项。找到 cross_prefix,按 i 键编辑,新增一行内容:
CMDLINE_SET="
$PATHS_LIST
ar
arch
as
assert_level
build_suffix
cc
objcc
cpu
cross_prefix
# 下面一行内容为新增命令行参数,原文件中没有
cross_prefix_clang
custom_allocator
cxx
dep_cc
# 省略其他.....
"
按 esc 键退出编辑模式,输入 /ar_default="${cross_prefix}${ar_default}",按下回车键来匹配设置项。按 i 键键入编辑:
# 原内容
ar_default="${cross_prefix}${ar_default}"
cc_default="${cross_prefix}${cc_default}"
cxx_default="${cross_prefix}${cxx_default}"
nm_default="${cross_prefix}${nm_default}"
pkg_config_default="${cross_prefix}${pkg_config_default}"
将中间两行修改为:
# 修改后的内容
ar_default="${cross_prefix}${ar_default}"
#------------------------------------------------
cc_default="${cross_prefix_clang}${cc_default}"
cxx_default="${cross_prefix_clang}${cxx_default}"
#------------------------------------------------
nm_default="${cross_prefix}${nm_default}"
pkg_config_default="${cross_prefix}${pkg_config_default}"
按 esc 键退出编辑,输入 :wq 保存退出。
注释:Vim 中,按 n(小写 n) 可以匹配下一个内容,按 shift+n 可以匹配上一个内容。输入 set nohlsearch(简写为:set-noh)来取消文本的高亮。
新增编译脚本文件:
touch build_android_clang.sh
修改脚本权限:
chmod 777 build_android_clang.sh
编辑脚本:
sudo vim build_android_clang.sh
按 i 键编辑,脚本文件内容如下:
#!/bin/bash
set -x # 执行指令后,先显示该指令及所下的参数。
# 目标Android版本
API=21
CPU=armv7-a
#so库输出目录
OUTPUT=/home/wenchen/android/so/$CPU
# NDK的路径,根据自己的NDK位置进行设置
NDK=/home/wenchen/android/ndk/ndk-r21e/android-ndk-r21e
# 编译工具链路径
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
# 编译环境
SYSROOT=$TOOLCHAIN/sysroot
function build
{
./configure \
--prefix=$OUTPUT \
--target-os=android \
--arch=arm \
--cpu=$CPU \
--enable-asm \
--enable-neon \
--enable-cross-compile \
--enable-shared \
--disable-static \
--disable-doc \
--disable-ffplay \
--disable-ffprobe \
--disable-symver \
--disable-ffmpeg \
--sysroot=$SYSROOT \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--cross-prefix-clang=$TOOLCHAIN/bin/armv7a-linux-androideabi$API- \
--extra-cflags="-fPIC"
make clean all
# 这里是定义用几个CPU编译
make -j8
make install
}
build
按 esc 键退出编辑,输入 :wq 保存退出。
写好编译脚本后,安装 make 命令:
sudo apt-get install make
执行编译脚本:
./build_android_clang.sh
关于编译脚本中的一些说明,可以看看** 这篇文章 **。脚本基本上都参考自它。
一路通畅,再也没有什么报错。在 so 目录下,可以找到 include、lib、share 三个目录,ffmpeg so 就在 lib 目录下,头文件在 include 目录下。
至于编译多种 CPU 架构的 so,其实搜下 shell 编程 for 循环就会了。