ijkplayer框架是B站开源的一款基于ffmpeg的轻量级视频播放器,同时支持 Android 和 iOS 平台。项目中使用了SJVideoPlayer视频播放三方中使用了ijkplayer,在此记录一下。
1. 从github上克隆ijkplayer
cd Desktop/
git clone https://github.com/Bilibili/ijkplayer.git ijkplayer
注意:此时的ffmpeg-arm64
,ffmpeg-armv7
,ffmpeg-i386
,ffmpeg-x86_64
是没有的,如果执行IJKMediaDemo
,则会报错找不到ffmpeg
框架中的库,需要下载ffmpeg
。
配置编解码器格式支持
默认为最少支持, 如果足够你使用, 可以跳过这一步. 否则可以改为以下配置:
module-default.sh
更多的编解码器/格式module-lite-hevc.sh
较少的编解码器/格式(包括hevc)module-lite.sh
较少的编解码器/格式(默认情况)
# 进入 config 目录
cd config
# 删除当前的 module.sh 文件
rm module.sh
# 可根据需要替换为`module-default.sh`, `module-lite-hevc.sh`, `module-lite.sh`
# 创建软链接 module.sh 指向 module-lite-hevc.sh
ln -s module-lite-hevc.sh module.sh
升级FFmpeg4.0版本
到 bilibili fork 的 FFmpeg 项目中的 releases
查看当前支持的最新版本。
打开 init-ios.sh
文件,修改 IJK_FFMPEG_COMMIT
。例如
IJK_FFMPEG_COMMIT=ff4.0--ijk0.8.8--20210426--001
打开 config/module-lite.sh
文件。修改以下内容
注释掉这两行:
#export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-ffserver"
#export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-vda"
增加:
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-bsf=eac3_core"
# 增加 https 协议支持(可选)
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-protocol=https"
升级openssl版本(增加 https 协议支持的可用)
到 bilibili fork 的 openssl 项目中的 releases
查看当前支持的最新版本。
打开 init-ios-openssl.sh
文件,修改 IJK_OPENSSL_COMMIT
。例如
IJK_OPENSSL_COMMIT=OpenSSL_1_0_2u
iOS需要播放加密的m3u8文件,后台把每个ts地址进行加密,客户端进行解密后播放。
打开 config/module-lite.sh
文件。修改以下内容
修改:
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-protocol=crypto",支持crypto协议.
2. 下载ffmpeg
cd ijkplayer
git checkout -B latest k0.8.8
./init-ios.sh
# 增加 https 协议支持(可选)
./init-ios-openssl.sh
注意:此过程会比较慢,下载完成之后在iOS的目录下则会出现ffmpeg
文件。这时候我们的 ffmpeg
就下载好了,此时再次运行IJKMediaDemo
发现还是报错,因为执行init-ios.sh,只是下载ffmpeg
源码,但是源码并没有参与编译,需要把源码编译成.a文件:
3. 编译ffmpeg
cd ios
./compile-ffmpeg.sh clean
./compile-ffmpeg.sh all
增加 https 协议支持(可选)
# 增加 https 协议支持(可选)
./compile-openssl.sh clean
./compile-openssl.sh all
打开IJKMediaFramework,如果没有下图的两个静态库,添加libcrypto.a和libssl.a这两个文件。
注意:1. 执行 ./compile-ffmpeg.sh clean
,目的是删除一些文件和文件夹,为编译ffmpeg.sh
做准备,在编译ffmpeg.sh
的时候,会自动创建刚刚删除的那些文件,为避免文件名冲突,因此在编译ffmpeg.sh
之前先删除等会会自动创建的文件夹或文件
2. 执行 ./compile-ffmpeg.sh all
目的是编译各个平台的ffmpeg
库,并生成所以平台的通用库。
3. 如果遇到此问题,表示不支持armv7:
- 解决办法:
- 打开ios目录下这个
compile-ffmpeg.sh
文件 - 第24行 改为:
FF_ALL_ARCHS_IOS8_SDK="arm64 i386 x86_64"
- 第120行 改为:
if [ "$FF_TARGET" = "armv7s" -o "$FF_TARGET" = "arm64" ]; then
- 第159行 改为:
echo " compile-ffmpeg.sh arm64|i386|x86_64"
- 再次执行
./compile-ffmpeg.sh clean
和./compile-ffmpeg.sh all
即可
- 打开ios目录下这个
4. 打包ijkplayer
通过以上3步,IJKMediaDemo
已经可以运行了,接下来就可以将ijkplayer进行静态库打包了。
打开下图工程,打包静态库,具体可参考我的文章iOS打包静态库framework中的第七步即可。
5. Xcode 13 在打开IJKMediaPlayer
时没有Products
,解决方案如下:
- 首先找到
IJKMediaPlayer.xcodeproj
双击显示包内容
- 双击打开
project.pbxproj
,搜索mainGroup
,可以看到。mainGroup
的值和productRefGroup
的值不一样,将mainGroup
的值替换掉productRefGroup
的值即可显示Products
文件
6. 真机command+B时报错 The linked library 'libavcodec.a' is missing one or more architectures required by this target: armv7.
等,解决方案如下:
- 在
Target-Build Settings-Excluded Architectures
中添加以下代码EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64=arm64 arm64e armv7 armv7s armv6 armv8
EXCLUDED_ARCHS=$(inherited)
$(EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_$(EFFECTIVE_PLATFORM_SUFFIX)__NATIVE_ARCH_64_BIT_$(NATIVE_ARCH_64_BIT))
7. 解决硬解码解码m3u8格式视频,部分手机切换后台,进入前台,画面暂停,有声音,日志recovery error!!!!
- 本人是使用
IJKVideoToolBoxSync.m
(注:上面链接解决方案中IJKVideoToolBox.m
没有static int decode_video
方法)中如下方法
static int decode_video(VideoToolBoxContext* context, AVCodecContext *avctx, AVPacket *avpkt, int* got_picture_ptr)
添加了下面这一句解决了问题
context->idr_based_identified = false
8. 补充:IJKPlayer可以支持硬解码H265格式的视频
以下在IJKVideoToolBoxAsync.m
和IJKVideoToolBoxSync.m
中操作
- 中注释掉
vtbformat_init
中的如下方法(我的默认是注释的)
//if (!validate_avcC_spc(extradata, extrasize, &fmt_desc->max_ref_frames, &sps_level, &sps_profile)) {
//goto failed;
//}
ff_isom_write_avcc
替换方法如下
//ff_isom_write_avcc(pb, extradata, extrasize);
if (codec == AV_CODEC_ID_HEVC) {
//hvcc isom is different from avcc'
ff_isom_write_hvcc(pb, extradata, extrasize, 1);
} else {
ff_isom_write_avcc(pb, extradata, extrasize);
}
-
以上方法调整完后
ff_isom_write_hvcc
方法是报错的,需打开
3.1ijkplayer
-ios
-extra
-ffmpeg
-libavformat
-Makefile文件
"HEADERS =" 加入 "hevc.h \ " “OBJS =” 中加入"hevc.o \ "
3.2ijkplayer
-ios
-ios
-arm64
-libavformat
-Makefile文件
"HEADERS =" 加入 "hevc.h \ " “OBJS =” 中加入"hevc.o \ " -
再次编译并重新打包(编译时ff_isom_write_hvcc可能依然报错,此时需要在
IJKVideoToolBoxAsync.m
和IJKVideoToolBoxSync.m
中添加头文件#include "libavformat/hevc.h"
)
cd iOS
./compile-ffmpeg.sh clean
./compile-ffmpeg.sh all
-
有人发现解H265数据时,如果带有HEVC_NAL_AUD帧会导致videotoolbox解码失败。有问题的朋友可排查一下
-
其他问题的朋友一起交流。
参考文章
1.ijkplayer iOS打包,支持HTTPS,升级ffmpeg4.0
2. IJKPlayer FFmpeg 4.x 编译
3. # 解决ijkplayer在iOS H265硬解码失败问题