為了方便以后查詢勺鸦,收藏呼神的博客
前言
保護好第三方的版權(quán)是視頻類公司要考慮的問題赫冬。如何防止用戶通過錄屏手段取得受版權(quán)保護的視頻就是我們要討論的內(nèi)容浓镜。
常見錄屏方法
- 越獄
- 私有Api
- AirPlay
- QuickTime
越獄
越獄后基本上想干啥都行了,小小的錄屏功能更是不在話下劲厌。越獄市場上也有很多插件支持錄屏的膛薛,隨便搞來一個用就好。
阻止方法
想防越獄也比較簡單补鼻,代碼里可以判斷當前設(shè)備是否越過獄哄啄,如果越獄了,就直接exit吧风范。判斷越獄的方法在念茜的博客里有比較詳細的介紹咨跌。
私有Api
以前有很多私有Api可以進行屏幕錄制,都是通過截取一張張的圖片來達到目的硼婿。但是隨著SDK的升級锌半,這些方法大多不管用了。目前能用的私有錄屏Api只有一種寇漫,也就是IOSurface私有庫刊殉。通過這個庫可以在iOS9以下的設(shè)備上實現(xiàn)后臺截屏功能,從而達到錄屏效果州胳。
阻止方法
從iOS9開始IOSurface庫錄屏的Api被去掉了记焊,對于這種錄屏手段我們的解決方法也比較簡單粗暴,直接讓自家的App從iOS9開始支持栓撞。除了這種方案沒有其他的有效手段了亚亲。
AirPlay
通過AirPlay可以把當前屏幕投影到另外的屏幕上,比如投到PC上腐缤。那么PC上就有不少應(yīng)用程序可以通過AirPlay錄屏了捌归。不光錄屏,還可以進行視頻剪輯岭粤,美化等一系列功能惜索。
阻止方法
通過AirPlay不論是投到PC上,還是在本地起一個AirPlay的虛擬服務(wù)投到本地剃浇,通過[UIScreen screens].count取到的屏幕個數(shù)都會大于1巾兆,如果檢測到屏幕個數(shù)大于1的話,可以直接exit或者暫停視頻播放彈出提示虎囚。
QuickTime
我們今天著重講這種錄屏方式角塑,這個比較王道了,蘋果自家出的應(yīng)用淘讥,也提供錄屏功能圃伶,而且錄出來的效果比其他方法的效果好很多。
阻止方法
QuickTime是通過抓取屏幕圖像流來進行錄屏的蒲列,它還有個優(yōu)化體驗的地方窒朋,就是如果當前屏幕中,有AVPlayer的話蝗岖,它將和AVPlayer做同步侥猩,如果你播的是mp4文件,就直接拿AVPlayer中的mp4流抵赢。如果你使用HLS的方式欺劳,它將會讀到你AVPlayer中下載下來的ts切片,拿到切片數(shù)據(jù)后進行播放錄制铅鲤。
聽起來相當霸道了划提,然而蘋果也給出了官方解答,簡單解釋一下就是通過給HLS流加密彩匕,可以達到防止錄屏的效果腔剂,因為AVPlayer雖然可以拿到切片,但是沒有key的話就無法對流進行解密驼仪。
HLS流是蘋果自家的流媒體傳輸協(xié)議掸犬,具體的概念就不在此贅述了,網(wǎng)上資料很多绪爸。蘋果的SDK中的AVPlayer對于HLS相關(guān)一系列的功能支持的都非常好湾碎,比如字幕,加解密這些功能奠货。
HLS加密普遍是通過AES-128的方式給視頻流加密介褥,服務(wù)端和客戶端都拿著同一個key,在m3u8文件中也會出現(xiàn)EXT-X-KEY字段:
EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.php?r=52",IV=0x9c7db8778570d05c3177c349fd9236aa
METHOD:加密方式
URI:解密key的url地址
IV:可以當做是加密用的鹽值
當AVPlayer開始加載m3u8文件時,會異步取ts切片和key柔滔,key如果通過http請求拿的話就比較危險了溢陪,可以考慮https,或者客戶端本地組裝key睛廊,比如和服務(wù)端的同學(xué)約定好形真,通過視頻ID,類型ID等參數(shù)拼接在一起超全,再經(jīng)過一系列加密后的結(jié)果作為key咆霜。
如果通過客戶端自己組裝key,組裝好后要塞給AVPlayer嘶朱,之后AVPlayer在拿到ts切片后蛾坯,會自己用key來解密匈睁。
如果想這么做的話悼枢,我們需要將EXT-X-KEY項改成下面的寫法:
EXT-X-KEY:METHOD=AES-128,URI="CustomScheme://priv.example.com/key.php?r=52",IV=0x9c7db8778570d05c3177c349fd9236aa
URI這一項的Scheme變成了CustomScheme,后邊具體是什么地址都不重要了漫拭,填個假的也可以改览。
AVPlayer在加載m3u8文件時下翎,如果遇到用戶自定義的Scheme,會認為你需要自己加載資源文件宝当,例如key或者是ts切片视事。從而進入如下回調(diào):
- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest {
dispatch_async(dispatch_get_main_queue(), ^{
NSString *scheme = [[[loadingRequest request] URL] scheme];
NSData *data = [self getDecryptKey];
if (data) {
[loadingRequest.dataRequest respondWithData:data];
[loadingRequest finishLoading];
}
});
return YES;
}
在回調(diào)中將自己組裝的key傳給AVPlayer,通過getDecryptKey函數(shù)獲得key之后庆揩,就把data值賦給loadingRequest.dataRequest俐东,再調(diào)用[loadingRequest finishLoading],AVPlayer就收到key了订晌,后續(xù)的ts切片就將利用這個key來進行解密虏辫。
EXT-X-KEY字段可以有很多,意味著不同的ts切片將使用不同的key來解密锈拨。
通過這種方式就可以防止QuickTime的錄屏砌庄,可以看到蘋果自己SDK的AVPlayer對于自己的協(xié)議支持的相當好,回調(diào)用起來也非常方便奕枢。
安卓同學(xué)如果想支持HLS解密的話比較麻煩娄昆,因為安卓官方的播放器沒有加載資源的回調(diào)。只能通過本地起Server缝彬,把key放到本地Server中萌焰,再替換EXT-X-KEY中的uri值來進行實現(xiàn)」惹常或者使用Google自家開源的更強大的播放器EXO來實現(xiàn)扒俯。
后記
HLS加密的方式還是比較普遍的奶卓,然而一直也沒有相關(guān)文章指出這種方式和QuickTime的防錄屏之間有什么關(guān)系。
有同學(xué)想問如果用RTMP或者其他方式播放視頻可以做到防錄屏嗎撼玄?只要你脫離AVPlayer去播放視頻夺姑,最終拿到的都是一幀幀的視頻畫面,然后渲染到屏幕上互纯,這樣的話AVPlayer都是可以拿到屏幕畫面流的瑟幕。
唯一的方式是將RTMP轉(zhuǎn)成HLS后加密,再通過AVPlayer來播留潦,如果不能這樣,就無法做到防錄屏辣往。