使用avplayer播放AES加密的hls流 - ios swift

时间:2016-08-24 13:32:16

标签: ios swift aes avplayer hls

我正在尝试在AVPlayer中播放AES加密流。通常,密钥的链接会传递给M3U8播放列表中的播放器..在我的场景中,密钥被分成两半..前半部分已交付由服务器和我应该在应用程序内附加另一半在播放时解密

我已经在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获取加密密钥时:'http://example.com/api/getEncryptionKey?t=57b5b16d3824d',我想拦截响应并附加密钥的另一半

有可能吗?

1 个答案:

答案 0 :(得分:2)

是的,这是非常有可能的!我最近在我的一个项目中做过。

每当AVPlayer加载加密视频时,它都会尝试从prog_index.m3u8中提到的URL加载解密密钥。如果AVPlayer无法使用提取的密钥播放视频,或者它没有在指定的网址上获取密钥,则会调用来自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,视频将立即播放。