本文记录了 ijkplayer 的编译完整流程,以及编译过程中遇到的坑及解决方案,如果不想自己编译,可以使用我编译好的结果。已放入 github: ijkplayer_Build4Android
编译好的 so 放在了 ijkplayer_Build4Android 项目的 ./build_output 目录中,基于 ijkplayer k0.8.8 ffmpeg 4.0(ff4.0–ijk0.8.8–20210426–001) 并包含 openssl、yuv、SDL
Ijkplayer 源码:https://github.com/bilibili/ijkplayer
Ijkplayer Tags 列表:https://github.com/bilibili/ijkplayer/tags
BiliBili OpenSSL Tags 列表:https://github.com/bilibili/openssl/tags
BiliBili FFmpeg Tags 列表:https://github.com/bilibili/FFmpeg/tags
vim ~/.zshrc
source ~/.zshrc
直接从 https://github.com/bilibili/ijkplayer/releases/tag/k0.8.8 下载最新版本 k0.8.8 代码,或用以下 git 命令拉取
git clone https://github.com/Bilibili/ijkplayer.git ijkplayer
cd ijkplayer
git checkout -B latest k0.8.8
我只需编译 armv7a 和 arm64,修改以下脚本,避免拷贝和编译多份不同架构的代码。
把以下这些脚本里的 pull_fork 只保留需要的架构。
init-android-openssl.sh
init-android.sh
init-android-libsoxr.sh
pull_fork "armv5"
pull_fork "armv7a"
pull_fork "arm64"
pull_fork "x86"
pull_fork "x86_64"
改成 =======>>>>
pull_fork "armv7a"
pull_fork "arm64"
把以下这些脚本里的 ACT_ABI_32 和 ACT_ABI_64 只保留需要的架构。
./android/contrib/compile-openssl.sh
./android/contrib/compile-libsoxr.sh
./android/compile-ijk.sh
ACT_ABI_32="armv5 armv7a x86"
ACT_ABI_64="armv5 armv7a arm64 x86 x86_64"
改成 =======>>>>
ACT_ABI_32="armv7a"
ACT_ABI_64="armv7a arm64"
ijkplayer k0.8.8 默认的 FFmpeg 的版本是 3.4,即 ff3.4–ijk0.8.7–20180103–001,现改成 FFmpeg 4.0 版本 ff4.0–ijk0.8.8–20210426–001,最新版本列表见:https://github.com/bilibili/FFmpeg/tags
在 init-android.sh 脚本中,改完后如下:
IJK_FFMPEG_UPSTREAM=https://github.com/Bilibili/FFmpeg.git
IJK_FFMPEG_FORK=https://github.com/Bilibili/FFmpeg.git
#IJK_FFMPEG_COMMIT=ff3.4--ijk0.8.7--20180103--001
IJK_FFMPEG_COMMIT=ff4.0--ijk0.8.8--20210426--001
IJK_FFMPEG_LOCAL_REPO=extra/ffmpeg
set -e
TOOLS=tools
git --version
echo "== pull ffmpeg base =="
sh $TOOLS/pull-repo-base.sh $IJK_FFMPEG_UPSTREAM $IJK_FFMPEG_LOCAL_REPO
function pull_fork()
{
echo "== pull ffmpeg fork $1 =="
sh $TOOLS/pull-repo-ref.sh $IJK_FFMPEG_FORK android/contrib/ffmpeg-$1 ${IJK_FFMPEG_LOCAL_REPO}
cd android/contrib/ffmpeg-$1
git checkout ${IJK_FFMPEG_COMMIT} -B ijkplayer
cd -
}
#pull_fork "armv5"
pull_fork "armv7a"
pull_fork "arm64"
#pull_fork "x86"
#pull_fork "x86_64"
./init-config.sh
./init-android-libyuv.sh
./init-android-soundtouch.sh
默认是精简版,完整版支持的格式更多,但是编译出的包体积更大,可根据自己的需要进行选择,本文编译的的精简版
cd config
rm module.sh
ln -s module-default.sh module.sh # 完整版
ln -s module-lite.sh module.sh # 精简版
ln -s module-lite-hevc.sh module.sh # 包含 HEVC 的精简版
# 下载指定的 ffmpeg 源码 ff4.0--ijk0.8.8--20210426--001
./init-android.sh
# 下载 openssl 源码,用于支持 https
./init-android-openssl.sh
# 在项目根目录下
cd android/contrib
# 编译 openssl
./compile-openssl.sh clean
./compile-openssl.sh all
# 编译 FFmpeg
./compile-ffmpeg.sh clean
./compile-ffmpeg.sh all
# 编译 ijkplayer
cd ..
./compile-ijk.sh all
注意:如期间遇到弹窗提示 ndk 的一些命令行工具不安全,不用管,选择【打开】或【取消】,在 Mac 的 【系统偏好设置】–>【安全性与隐私】的提示里选择【仍然允许】
error: undefined reference to ‘OBJ_create’
error: ld returned 1 exit status
../libcrypto.a(ec_pmeth.o):ec_pmeth.c:function pkey_ec_ctrl_str: error: undefined reference to 'OBJ_ln2nid'
../libcrypto.a(asn_moid.o):asn_moid.c:function oid_module_init: error: undefined reference to 'OBJ_create'
../libcrypto.a(asn_moid.o):asn_moid.c:function oid_module_init: error: undefined reference to 'OBJ_create'
collect2: error: ld returned 1 exit status
make[2]: *** [link_app.] Error 1
make[1]: *** [openssl] Error 2
make: *** [build_apps] Error 1
./compile-openssl.sh all
失败原因:多线程编译导致
解决方案:改成单线程编译,参考链接:
需要修改的脚本:./android/contrib/tools/do-detect-env.sh #91 行的
# 原本下面是通过系统命令 "sysctl -n machdep.cpu.thread_count" 来获取并设置编译线程数的,比如我电脑获取的是 8
export IJK_MAKE_FLAG=-j`sysctl -n machdep.cpu.thread_count`
改成 =======>>>>
# 强行改成单线程编译
export IJK_MAKE_FLAG=-j1
Unknown option “–disable-ffserver”.
--------------------
[*] check ffmpeg env
--------------------
OpenSSL detected
--------------------
[*] configurate ffmpeg
--------------------
/Users/wangjianjun/Alan/OpenSrcCode/ijkplayer_k0.8.25_ffmpeg4.0/ijkplayer-k0.8.8/android/contrib/build/ffmpeg-armv7a/toolchain/bin//arm-linux-androideabi-gcc
Unknown option "--disable-ffserver".
See ./configure --help for available options.
出错原因:ffmpeg 4.0 删除了 ffserver
解决方案:注释掉 ffserver 配置,参考链接,修改 config/module.sh 文件,注释掉以下两行:
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-ffserver"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-vda"
error: undefined reference to ‘ff_ac3_parse_header’
出错原因:ffmpeg 4.0 不再支持 eac3
解决方案:禁掉 eac3,参考链接,修改 config/module.sh 文件,增加如下一行:
# 在 export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-bsfs" 下方添加:
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-bsf=eac3_core"
Android NDK: Host ‘awk’ tool is outdated. Please define NDK_HOST_AWK to point to Gawk or Nawk !
解决方案:参考链接
1、进入到目录: android-ndk-r10e/prebuilt/darwin-x86_64/bin
2、将 awk 重命名为 awk_