ShareREC for iOS錄屏原理解析

2021-08-14 13:14:46 字數 2841 閱讀 9444

眾所周知,由於ios系統的封閉性,也出於保護使用者隱私的角度,蘋果並沒有公開的api供開發者呼叫,來錄製螢幕內容。導致許多遊戲或者應用沒有辦法直接通過呼叫系統api的方式提供錄製功能,使用者也無法將自己一些玩遊戲的過程錄製下來分享到其他玩家。基於此,sharerec應運而生。下面我們從說一下sharerec的錄屏的實現原理。

由於蘋果ui是基於不同的引擎渲染,所以目前針對不同的引擎,主要是採用以下幾種不同的方式實現:

(2) opengl 。由於 unity 3d 或 cocos2d兩種引擎,在ios裝置上都是採用opengl es這個底層庫實現渲染,所以後面會將兩者放在opengl中一起討論。

(3) metal。metal是蘋果推出的專門針對iphone和ipad中gpu程式設計高度優化的框架。目前unity 5已經支援64位ios metal技術,匯出xcode專案時,可以進行選擇。metal這個名稱的**是想說明這個圖形框架的的確確是非常底層的- -底層到已經非常接近金屬板了(metal)。

ps:(1)如果是基於越獄系統,開發者還可以通過呼叫系統的私有api方式,其中比較重要乙個方法是uigetscreenimage來實現錄製功能,這種方式的優點是錄製效率高且是無損畫質,但同時也有乙個致命的弱點,就是應用沒辦法上架。

目前sharerec支援opengl和metal兩種渲染引擎的錄製,上面提到過unity3d與cocos2d底層其實也是通過opengl來渲染的,所以在其上面開發的遊戲,sharerec均是完美支援的。sharerec是通過hook(鉤子)的方式,捕捉螢幕畫面,進行錄製的;其中心原理是首先捕獲到當前繪製的內容,此時拿到繪製的紋理後,可以自行進行處理;然後重新將內容繪製到螢幕上【這一步很重要,否則由於已經渲染的內容被鉤取,螢幕上將不會顯示任何內容】。下面我們將分別介紹sharerec捕獲兩種引擎opengl和metal的實現原理。

opengl:

首先ios系統預設支援opengl es 1.0、es2.0以及es3.0 (opengl es是opengl在移動端的簡化版本)三個版本,三者之間並不是簡單的版本公升級,設計理念甚至完全不同。所以我們後續的一些操作還會對於版本的不同分別做處理。廢話不多說,首先我們是要先通過鉤子,獲取到當前繪製的上下文物件context(context是乙個非常抽象的概念,我們姑且把它理解成乙個包含了所有opengl狀態的物件,如果我們把乙個context銷毀了,那麼opengl也不復存在)。畫了乙個圖,僅供理解。

然後根據當前的context,建立捕獲螢幕紋理cvoopenglestextureref,隨後建立中間渲染紋理;最後繫結紋理到fbo上面,此時,原本繪製到螢幕上的內容,將轉為繪製到我們建立的中間渲染紋理上面。此時,當opengl再次渲染螢幕內容時,將會首先被我們建立的螢幕紋理捕獲,從而拿到渲染內容;最後再重新將渲染畫面輸出到螢幕。其實現流程如圖所示:

其中繫結紋理到fbo的**如下:

上面主要闡述建立自己的rendertexture後,然後通過繫結紋理到fbo上面,執行這樣的操作以後,原本輸出到螢幕上的內容,將轉為繪製到rendertexture中,然後再建立輸出螢幕fbo,以及截圖的fbo;最後再通過_capturefbo畫入捕捉紋理,通過_outfbo輸出到螢幕。

目前很多api都通過具體的「類」來實現平台支援,不過metal使用的方法是基於「協議」的。因為metal中具體的型別是由執行的裝置所決定的。這很好的鼓勵了程式設計師選擇面向介面程式設計而非面向實現,以降低程式的耦合。當然也意味著需要冒著風險大量的在objective-c 執行時來對metal的型別新增繼承和擴充套件型別。

其整個流程如下圖所示。

但協議的這種方式,又無形中增加了我們鉤子的複雜程度。因為我們沒有辦法直接拿到相關的類;同時又考慮到相容低版本xcode環境的問題,我們也無法直接匯入metal框架,只能通過動態載入metal.framework的方式。只能通過動態(nsclassfromstring和nsselectorfromstring)獲取相關類和方法的方式來鉤取。同時基於「協議」的類,就只能通過dlsym/dlopen【最近蘋果對熱更新的審核比較嚴格,這種動態方法盡量還是少用】的方式獲取。再來說一下具體實現。其根本也是通過鉤子進行的。其中乙個最重要的乙個鉤子是presentdrawable:,這個主要是用於展示最終的渲染內容到螢幕上面的函式,其中有乙個最重要的引數mtldrawableref,這個引數就是乙個可繪製物件,也包含了最終要展示到螢幕的紋理。當我們取得最後展示到螢幕的drawable後,最後呼叫copytextureaction方法將勾取到的內容畫回螢幕:

至此,整個metal的錄製過程就結束了。最後,將獲取到的cvpixelbufferref按照指定格式寫入檔案。

上面就是sharerec ios分別對於opengl es和metal兩種引擎的渲染的錄製過程。其核心的方式就是通過hook的方式鉤取最後要渲染的內容,然後再將原來的內容重新渲染到螢幕上。

文/mob開發者平台 ios開發專家 李永超

c 錄屏 FFmpeg錄屏 錄屏格式轉換

需要對軟體的客戶區進行錄屏,但是找了半天資料發現並不好整合到我的軟體當中,最後發現利用cmd命令呼叫ffmpeg.exe可以實現錄屏功能,實現錄屏以及錄屏格式轉換,相當有趣。ffmpeg有乙個專用於windows下螢幕錄製的裝置 gdigrab。gdigrab是基於gdi的抓屏裝置,可以抓取螢幕的特...

Android screenrecord錄屏教程

1 android真機錄屏簡介 android 4.4 kitkat api 19 介紹了 screenrecord shell命令,這使開發人員使用adb shell screenrecord 命令便可記錄裝置的螢幕作為乙個mp4 adb 必須公升級到v19以上。2 android錄屏實現 通過 ...

Mac如何錄屏 同時錄內建聲音

首先需要乙個外掛程式,叫做soundflower 步驟如下 下完就配置環境 開啟 中的 音訊midi設定 開啟這個介面,點加號可以加 聚集裝置 和 多輸出裝置 這兩種模式,聚集裝置 的設定可以如下圖 然後就完事了,開啟螢幕錄製設定那裡,就可以看到這幾個選項 其中,聚集裝置 就是系統聲音 麥克風聲音 ...