业界都知道苹果是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:
,存在即是合理的:
-
iOS 11
和iOS12
容易出现启动录屏失败,而且这种失败是无法通过再次调用API启动成功的,只能通过重启手机才能恢复录屏功能 -
iOS 13
也存在杀进程才能录屏启动成功的情况,特别是使用系统录屏去中断App的录屏时,容易发生iOS11和iOS12只能通过重启手机恢复录屏功能的问题 (相较于iOS12及以下相对稳定,所以腾讯云官方文档也是"应用分享屏幕,该特性需要 iOS 13 及以上版本的操作系统才能支持"这样说,看来也没少踩坑...) - 频繁切换前后台容易丢失视频帧数据,也就是苹果录屏状态是
isRecording
,但实际上回调的只有AudioApp
类型的buffer
也就是app的音频流数据,这种数据流并不能像麦克风音频流数据一样设置接口去屏蔽它,因为苹果未开放这样的接口, 那么我又尝试了在回调方法里去记录不同的流做区分,可后来我发现其实音频和视频数据不是一一对应的,也不是有序的,音频数据流比视频流数据返回的频率高很多,这就又陷入难题了,只能尽可能少的去切换前后台以及增加切到前台时做重试机制,因为切换前后台很频繁,画面静止时不会产生视频帧数据,可能是重复的相似度极高的画面,导致苹果很长时间才有视频流数据返回,这一点各大平台SDK(七牛和腾讯云)也有共同的认识,七牛官方文档并未提及SDK是如何处理的,腾讯云SDK则是做补帧操作以保证达到配置的视频帧率。
腾讯云SDK:
系统分发视频 sampleBuffer 的频率并不固定,如果画面静止,可能很长时间才会有一帧数据过来。SDK 考虑到这种情况,内部会做补帧逻辑,使其达到 config 所设置的帧率(默认为20fps)
建议保存一帧给推流启动时使用,防止推流启动或切换横竖屏时因无新的画面数据采集发送,因为画面没有变化时系统可能会很长时间才采集一帧画面。
目前我的解决方案如下(不一定对):
- 加业务弹窗提示,录屏过程中建议不要频繁切换App应用的前后台,不然可能导致数据丢失的风险... (显然产品不会接受~)
- 因为
ReplayKit
开始录屏方法是用枚举区分三路不同数据流的一个回调,我们可以在回调方法里做判断,虽然说调用有些频繁可能导致额外的CPU
占用,但是这也是没有办法的事,因为系统壁垒无法攻破~ ,只能尽人事把它完善好一点点~, 我的做法是在bufferType == .Video
时, 记录一个时间戳, 在其后面用当前时间戳相减进行判断,是否大于1秒,如果说大于1秒没有视频流返回,那么将进行重试录屏操作 (调用停止录屏 + 再次调用开启录屏方法)
?? 重试需注意的问题:
注意开启一个录屏会话和结束一个录屏会话的时间间隔, 不然会发现系统ReplayKit
给你报-5829 由于未处于录制状态时尝试停止录制而失败
和-5830 由于已处于录制状态时尝试开始录制而失败
的错误 (频繁切换前后台必现,正常人谁玩这么猛~) 偶尔还有-5803屏幕录制启动失败
开启录屏处理, 我用了 sleep
+ 时间戳进行比对, 也就是1~2
秒内不得再次调用开启录屏API
, 而结束录屏时加上一个判断是否录屏中的状态再停止录屏操作即可,主要是开启不得过于频繁,之前摸索过程中也试过每次切入前台加延时进行重试,但是稳定性和准确性没法保证,属于宁可错杀不可放过的做法~
哎??,心塞~ 辣鸡苹果?,bug可真多~ iOS开发没有人要了