業界都知道蘋果是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開發沒有人要了