很多人對螢幕共享的印象還隻停留在 PC 端做 PPT 彙報的場景中,但事實上,今天的螢幕共享早已跨界出圈了。比如一個大家很熟悉的場景 —— 遊戲直播,主播就需要将自己的畫面以“螢幕共享”的形式展示給觀衆,并且對實時性、流暢性的要求非常高。
對于很多手遊主播來說,目前比較常見的做法是,通過借助 PC 端的中轉将手機遊戲畫面進行直播分享;而實際上,通過調用融雲螢幕共享 SDK,直接在手機端就可以擁有螢幕實時共享的能力。
本文就将主要圍繞 iOS 螢幕共享問題展開讨論,一起了解 iOS ReplayKit 架構的發展過程,各個階段的功能演變,以及結合融雲螢幕共享 SDK 實作相應功能的代碼和思路。
01 ReplayKit 發展史
iOS 端螢幕錄制 ReplayKit 是從 iOS9 開始出現的。
iOS9
WWDC15 初次提供 ReplayKit 架構,它的初期出現主要用于錄制視訊,存于相冊。
iOS9 開始錄制和停止錄制兩個 API 有很大的局限性:
隻能擷取系統生成好的 MP4 檔案,且不能直接擷取,需要先儲存到相冊,再從相冊擷取;
不可以擷取源資料,也就是 pcm 和 yuv 資料;
給開發者的權限低,不能錄制其他 APP,且退出背景就不會錄制了,隻能錄制目前 APP 畫面。
可控行為在于:
停止錄制可彈出一個視訊預覽視窗,能進行儲存或取消或分享該視訊檔案;
錄制完成後可以進行檢視、編輯,或者通過指定方式分享。
開始錄制視訊的 API 如下所示。
調用開始錄屏的時候,系統會彈出一個彈窗,需要使用者進行确認後才能正常錄制。
(圖1 啟動系統錄制彈窗)
停止錄制視訊的 API 如下所示。
(圖2 錄制螢幕完成系統頁面)
iOS10
經過 WWDC16 釋出,蘋果對 ReplayKit 進行了更新,開放了源資料擷取途徑,增加了兩個 Extension 的 Target。具體情況包括:
新增 UI 和 Upload 兩個 Extension 的 Target;
增加開發者權限,允許使用者登入到服務并設立了直播、源資料的操作;
隻能通過擴充區錄制螢幕,不僅可以錄制自己的 APP,還可以錄制其他 APP;
隻能錄制 APP 螢幕,不能錄制 iOS 系統螢幕。
建立 Extension 的方法如下圖所示。
(圖3 建立 Extension 圖示)
UI Extension
Upload Extension
Host APP
iOS11
經過 WWDC17,蘋果對 ReplayKit2 進行了再次更新,新增了 APP 外資料擷取,可以直接在 Host App 中擷取,具體包括:
可以直接在 Host APP 中處理錄制的 APP 螢幕資料;
可以錄制 iOS 系統的螢幕資料,但是需要通過控制中心手動開啟。
啟動 APP 螢幕錄制
停止 APP 螢幕錄制
iOS12
蘋果在 WWDC18 上針對 ReplayKit 更新,新增了 RPSystemBroadcastPickerView,類用于在 APP 内可啟動系統錄制,極大地簡化了螢幕錄制的流程。
02 融雲 RongRTCReplayKitExt
為減輕開發者的內建負擔,融雲專門打造了 RongRTCReplayKitExt 庫,以服務于螢幕共享業務。
設計思路
SampleHandler 進行資料的接收、RCRTCReplayKitEngine 初始化配置 ;
RCRTCReplayKitEngine 初始化 socket 通訊、處理YUV資料轉i420、控制記憶體峰值。
App
原有釋出流程:
IM 連接配接--加入房間--釋出資源(RCRTCScreenShareOutputStream);
内部做 socket 初始化、實作協定接收處理過的資料、推流 。
(圖4 設計思路流程圖)
代碼示例
Upload extension
Host App
03 一些注意事項
第一,ReplayKit2 記憶體不能超過 50MB,一旦超過峰值系統會進行強制回收,是以在 Extension 裡面處理資料需要格外注意記憶體釋放。
第二,程序之前通訊,如果是以 CFDefaultcenter 不能攜帶參數,隻能發送消息;如果需要攜帶參數,必須做本地檔案緩存。這裡需要注意的一個問題是,在 debug 模式下運作可以列印出資料,在 release 下擷取不到本地檔案資料,具體實作可參見 Github 中的攻略。
最後想小小吐槽一下:非正常結束錄屏時,系統往往會出現彈窗,且這個彈窗無法删除,隻能重新開機裝置 —— 這應該算是 iOS 系統一個比較惱人的 BUG 了。