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

Had*_*jem 5 aes http-live-streaming ios avplayer swift

我正在尝试在 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
Run Code Online (Sandbox Code Playgroud)

这是块列表:

#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
Run Code Online (Sandbox Code Playgroud)

这就是 AVPlayer 所做的:

1- 下载播放列表并选择块列表 2- 播放器下载块列表 3- 下载解密块的解密密钥 4- 播放器开始顺序下载块以播放它们 5- 每个块都被解密并且玩过

我需要做的是:在第三步之后,当玩家调用 api 使用此链接获取加密密钥时:' http : //example.com/api/getEncryptionKey?t=57b5b16d3824d ',我想拦截响应并附加密钥的另一半

是否可以?

abh*_*y23 4

是的,这很有可能!我最近在我的一个项目中做到了这一点。

每当AVPlayer加载加密视频时,它都会尝试从 prog_index.m3u8 中提到的 URL 加载解密密钥。如果 AVPlayer 无法使用获取的密钥播放视频,或者根本没有在指定的 url 上获取密钥,它将调用一个委托方法,AVAssetResourceLoaderDelegate

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

和,

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

当然,它们被称为的情况有所不同。前一个在玩家需要等待加载资源时调用,后一个在玩家需要更新资源时调用。

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;
}}
Run Code Online (Sandbox Code Playgroud)

一旦您使用实际密钥返回 true,视频将立即播放。