2016-08-24 160 views
2

我試圖播放AVPlayer中的AES加密流..通常是一個鏈接的關鍵是傳遞給M3U8播放列表中的播放器..在我的情況下,關鍵是分成一半..上半年是由服務器交付,我應該追加在應用程序內的另一半解密時玩使用avplayer播放AES加密hls流 - ios swift

我已經在Android上做到這一點,有沒有辦法做到這一點,也在iOS上?

這是播放列表:

#EXTM3U 
#EXT-X-VERSION:3 
#EXT-X-STREAM-INF:BANDWIDTH=200000,RESOLUTION=284x160 
chunklist_w670540365_b200000.m3u8?t=57b5b16d3824d 
#EXT-X-STREAM-INF:BANDWIDTH=850000,RESOLUTION=640x360 
chunklist_w670540365_b850000.m3u8?t=57b5b16d3824d 

這是塊列表:

#EXTM3U 
#EXT-X-VERSION:3 
#EXT-X-ALLOW-CACHE:NO 
#EXT-X-TARGETDURATION:11 
#EXT-X-MEDIA-SEQUENCE:13544 
#EXT-X-KEY:METHOD=AES-128,URI="http://example.com/api/getEncryptionKey?t=57b5b16d3824d" 
#EXTINF:9.6, 
media_w670540365_b200000_13544.ts?t=57b5b16d3824d 
#EXTINF:9.6, 
media_w670540365_b200000_13545.ts?t=57b5b16d3824d 
#EXTINF:10.56, 
media_w670540365_b200000_13546.ts?t=57b5b16d3824d 

這是AVPlayer做:

1-播放列表會下載並選擇一個塊列表 2-播放器的下載列表塊3- 解密密鑰來解密塊被下載 4-玩家開始下載塊的順序播放這些 5塊每次被解密並播放

什麼,我需要做的是: 當玩家調用API使用這個鏈接來獲得加密密鑰的第3步後:「http://example.com/api/getEncryptionKey?t=57b5b16d3824d」 ,我想攔截迴應並追加另一半的鑰匙

可能嗎?

回答

0

是的,這是非常可能的!我最近在我的一個項目中做過。

每當AVPlayer加載加密視頻時,它會嘗試從prog_index.m3u8中提到的URL加載解密密鑰。如果AVPlayer是無法與取出的密鑰來播放視頻,或者如果它沒有拿到鑰匙都在指定的URL,它調用從AVAssetResourceLoaderDelegate委託方法是

public func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForRenewalOfRequestedResource renewalRequest: AVAssetResourceRenewalRequest) -> Bool { 
    return shouldLoadOrRenewRequestedResource(resourceLoadingRequest: renewalRequest) 
} 

,並

public func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool { 
    return shouldLoadOrRenewRequestedResource(resourceLoadingRequest: loadingRequest) 
} 

當然,它們在被調用的情況下不同。在玩家需要等待加載資源時調用先前的一個,然後在玩家需要更新資源時調用稍後的一個。

func shouldLoadOrRenewRequestedResource(resourceLoadingRequest: AVAssetResourceLoadingRequest) -> Bool { 

    guard var url = resourceLoadingRequest.request.url else { 
     return false 
    } 

    //FETCH THE KEY FROM NETWORK CALL/KEYSTORE, CONVERT IT TO DATA AND FINISH LOADING OF RESOURCE WITH THAT DATA, IN YOUR CASE JOIN THE OTHER HALF OF THE KEY TO ACTUAL KEY (you can get the first half from the url above) 
    resourceLoadingRequest.dataRequest?.respond(with: keyData) 
    resourceLoadingRequest.finishLoading() 

    return true; 
}} 

一旦你用真正的鍵返回true,視頻就會立即播放。