当项目中使用ijkplayer,而且还需要播放HTTPS链接的视频时,就比较蛋疼了 ( ̄. ̄),ijkplayer默认不支持HTTPS播放,但提供了编译OpenSSL的选项,可以自己编译so文件支持HTTPS播放。这篇文章的目的是引导不熟悉的人完成整个编译过程,提醒过程中的注意事项,还有各种选项的解释。
我的编译环境
VMware + Ubuntu编译环境也可以参考,基本上只有命令不同,homebrew的安装这里不再赘述。非常不建议在Windows环境下编译!1
2
3
4
5
6Mac 10.13.2
iTerm2 + zsh
HomeBrew
NDK r10e
NDK + 编译所有so大概需要10GB空间
相关链接:
1. 准备工作
安装Git与yasm
1 | brew install git |
配置SDK、NDK
SDK都会有,NDK一般没有下载,建议去官网下载:https://developer.android.google.cn/ndk/downloads/older_releases
需要注意的是最好下载官方lib使用的NDK r10e,使用其他版本的将无法编译。具体原因可以参考这篇issue
SDK、NDK和准备完成后,在.bash_profile
, 或者是.zshrc
中添加配置。(Command + shift + .
显示隐藏文件)
1 | // 注意替换为自己的文件路径 |
添加完成后,保存文件,然后source .bash_profile
等相关文件,或者直接重启终端,通过 ndk-build -v
检查是否生效
clone ijkplayer源码
1 | git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-android |
2. 编译之前
编译前选择你的配置
选择自动化编译时的一些配置选项,比如支持的协议,音视频类型等,官方给我们提供了三个模板。
可以打开config/目录下config/module.sh看看,enable启用,disable禁用1
2
3module-default.sh
module-lite-hevc.sh
module-lite.sh
官方默认建议选择的是 module-lite.sh
,可以根据自己的需求选择1
2
3cd config
rm module.sh
ln -s module-lite.sh module.sh
如果要选择module-default.sh
的话,可能会编译失败,可以参考这篇issue1
2
3仔细阅读module-lite.h 原来在最下面有一行配置:
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-linux-perf"
把这行复制到module-default.sh 的最后面就可以了
在编译配置中可以增减需要的模块,选择需要支持的封装格式、编解码类型、协议能有效减小so库的体积。可以参考CarGuo/GSYVideoPlayer DECODERS.md
3. 开始编译ヽ(`⌒´)ノ
执行初始化
初始化会下载各种包,尽量选择在良好的网络环境下╮( ̄▽ ̄)╭1
2cd ..
./init-android.sh
初始化OpenSSL1
./init-android-openssl.sh
编译OpenSSL和FFmpeg
首先清除一波1
2
3cd android/contrib
./compile-openssl.sh clean
./compile-ffmpeg.sh clean
编译OpenSSL:可以选择不同版本,全量编译耗时更长,但最好选择全量编译,编译完成后再根据需求选择要使用的包。1
./compile-openssl.sh all
编译FFmpeg,同样的1
2
3./compile-ffmpeg.sh all
// 如果要选择特定的架构: ./compile-ffmpeg.sh armv7a | armv5
最后编译ijkplayer1
./compile-ijk.sh all
经过漫长的等待终于完成了以上编译过程\( ̄︶ ̄)/,在目录中生成了ijkplayer的工程
4. 导入项目
原有的项目一般是这样配置的1
2implementation 'tv.danmaku.ijk.media:ijkplayer-java:' + gradle.ijkplayer_java
implementation 'tv.danmaku.ijk.media:ijkplayer-armv7a:' + gradle.ijkplayer_java
如果只需要修改so库的话,删除掉第二行对so库的引用,将自己编译好的so文件复制到项目的libs文件夹中。
别忘了在gradle中配置,要不然会报错找不到so库
还可以在release包中设置abi过滤
最后大功告成啦\(^o^)/
尾巴…
如果项目中同时使用了HTTP和HTTPS的视频源的话,要注意如果视频源刚好是相同域名,会导致播放失败,这是由于dns缓存造成的,解决办法参考这篇issue
初始化IjkMediaPlayer
时,设置清除dns cache
1
2
3
4
5
6
7IjkMediaPlayer.OPT_CATEGORY_FORMAT, "dns_cache_clear", 1
//还要注意开启相关支持的协议
IjkMediaPlayer.OPT_CATEGORY_FORMAT, "protocol_whitelist",
"async,cache,crypto,file,http,https,ijkhttphook,ijkinject,
ijklivehook,ijklongurl,ijksegment,ijktcphook,
pipe,rtp,tcp,tls,udp,ijkurlhook,data"