关于iOS ReplayKit录屏推流遇到的坑

业界都知道苹果是BugOS,特别是最近几年bug越来越多了,总结一下我在使用ReplayKit做录屏推流过程中遇到的坑~

目前iOS录屏有以下几种常见的方案

方案 实现原理 优点 缺点
ReplayKit 应用拓展Broadcast Upload Extension iOS11以上可用,需要添加应用拓展,将拓展录制的数据提供给宿主app 稳定,应用内外均可录制 50MB内存限制
ReplayKit应用内屏幕抓取数据流startCaptureWithHandler: iOS11以上支持,但是iOS11和iOS12有着大量的bug, 需iOS13以上才稳定可用 应用内录屏,轻量级,高性能 版本差异较大,兼容性问题明显
ReplayKit应用内录屏视频文件startRecordingxxx iOS9.0以上可用,提供系统自带的预览分享页面 系统自带,兼容低版本 不灵活,不能自定义预览页面(网上很多hack方案)
ReplayKit系统录屏 在控制中心添加,由用户操作,录制完会生成视频到系统相册 系统自带,啥都能录下来 不灵活,未提供接口给开发者使用
自定义方案 定时器 + 截图渲染生成视频流数据 灵活可控,可确保不丢帧 比较损耗性能,一些特殊的视图或者Layer动画等无法录制下来

我们项目用的应用内录屏startCaptureWithHandler:,存在即是合理的:

  1. iOS 11iOS12 容易出现启动录屏失败,而且这种失败是无法通过再次调用API启动成功的,只能通过重启手机才能恢复录屏功能
  2. iOS 13也存在杀进程才能录屏启动成功的情况,特别是使用系统录屏去中断App的录屏时,容易发生iOS11和iOS12只能通过重启手机恢复录屏功能的问题 (相较于iOS12及以下相对稳定,所以腾讯云官方文档也是"应用分享屏幕,该特性需要 iOS 13 及以上版本的操作系统才能支持"这样说,看来也没少踩坑...)
  3. 频繁切换前后台容易丢失视频帧数据,也就是苹果录屏状态是isRecording,但实际上回调的只有AudioApp类型的buffer也就是app的音频流数据,这种数据流并不能像麦克风音频流数据一样设置接口去屏蔽它,因为苹果未开放这样的接口, 那么我又尝试了在回调方法里去记录不同的流做区分,可后来我发现其实音频和视频数据不是一一对应的,也不是有序的,音频数据流比视频流数据返回的频率高很多,这就又陷入难题了,只能尽可能少的去切换前后台以及增加切到前台时做重试机制,因为切换前后台很频繁,画面静止时不会产生视频帧数据,可能是重复的相似度极高的画面,导致苹果很长时间才有视频流数据返回,这一点各大平台SDK(七牛和腾讯云)也有共同的认识,七牛官方文档并未提及SDK是如何处理的,腾讯云SDK则是做补帧操作以保证达到配置的视频帧率。

腾讯云SDK:

系统分发视频 sampleBuffer 的频率并不固定,如果画面静止,可能很长时间才会有一帧数据过来。SDK 考虑到这种情况,内部会做补帧逻辑,使其达到 config 所设置的帧率(默认为20fps)

建议保存一帧给推流启动时使用,防止推流启动或切换横竖屏时因无新的画面数据采集发送,因为画面没有变化时系统可能会很长时间才采集一帧画面。

目前我的解决方案如下(不一定对):

  1. 加业务弹窗提示,录屏过程中建议不要频繁切换App应用的前后台,不然可能导致数据丢失的风险... (显然产品不会接受~)
  2. 因为ReplayKit开始录屏方法是用枚举区分三路不同数据流的一个回调,我们可以在回调方法里做判断,虽然说调用有些频繁可能导致额外的CPU占用,但是这也是没有办法的事,因为系统壁垒无法攻破~ ,只能尽人事把它完善好一点点~, 我的做法是在 bufferType == .Video 时, 记录一个时间戳, 在其后面用当前时间戳相减进行判断,是否大于1秒,如果说大于1秒没有视频流返回,那么将进行重试录屏操作 (调用停止录屏 + 再次调用开启录屏方法)

?? 重试需注意的问题:

注意开启一个录屏会话和结束一个录屏会话的时间间隔, 不然会发现系统ReplayKit给你报-5829 由于未处于录制状态时尝试停止录制而失败-5830 由于已处于录制状态时尝试开始录制而失败的错误 (频繁切换前后台必现,正常人谁玩这么猛~) 偶尔还有-5803屏幕录制启动失败

开启录屏处理, 我用了 sleep + 时间戳进行比对, 也就是1~2秒内不得再次调用开启录屏API , 而结束录屏时加上一个判断是否录屏中的状态再停止录屏操作即可,主要是开启不得过于频繁,之前摸索过程中也试过每次切入前台加延时进行重试,但是稳定性和准确性没法保证,属于宁可错杀不可放过的做法~

哎??,心塞~ 辣鸡苹果?,bug可真多~ iOS开发没有人要了

参考文章

关于iOS ReplayKit录屏推流遇到的坑

上一篇:ios真机调试,iTunes检测得到,hbuilder未检测到手机和模拟器的解决办法


下一篇:直播视频app源码,Android获取状态栏高度,动态设置控件高度