繁体   English   中英

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

[英]Playing AES encrypted hls stream using avplayer - ios 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

这是块列表:

 #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 ',我想拦截响应并附加密钥的另一半

是否可以?

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

每当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,视频将立即播放。

在尝试使用 Azure 媒体服务时,以下示例可以正常工作。 在这里,我们将令牌添加为 AVURLAsset 选项的一部分。

    var options = [String: [String: String]]()
    if (!token.isEmpty) {
        let headers = ["Authorization": "Bearer " + token!]
        options = ["AVURLAssetHTTPHeaderFieldsKey": headers]
    }
    let avAsset = AVURLAsset(url: videoUrl, options: options)
    let avItem = AVPlayerItem(asset: avAsset)
    let player = AVPlayer(playerItem: avItem)
    
    let playerFrame = view.viewWithTag(1)?.frame
    controller.player = player
    if (autoPlay.isOn) {
        player.rate = 1
    }
    controller.view.frame = playerFrame ?? CGRect(x: 0, y: 0, width: view.frame.width , height: 250)
    addChild(controller)
    view.viewWithTag(1)?.addSubview(controller.view)
    controller.didMove(toParent: self)
    

完整的工作样本可以从

https://github.com/Azure-Samples/media-services-3rdparty-player-samples/tree/master/src/avplayer

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM