【问题标题】:Playing AES encrypted hls stream using avplayer - ios swift使用 avplayer 播放 AES 加密的 hls 流 - ios swift
【发布时间】:2016-08-24 13:32:16
【问题描述】:

我正在尝试在 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- 每个块都被解密和播放

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

有可能吗?

【问题讨论】:

  • 您是如何在 Android 中做到这一点的?请分享一些Android的示例代码。我在 iOS 上做过,但在 Android 上卡住了
  • @Vashum 是的,我已经在 android 上完成了,你在 android 上使用什么视频播放器?
  • EXO玩家,你能帮忙吗?任何示例代码都会很棒????
  • 你能帮忙吗?
  • 嗨@HadiNajem,你能分享你的Android自定义数据源代码吗,因为我坚持在Android上实现这个。

标签: ios swift aes avplayer http-live-streaming


【解决方案1】:

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

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

【讨论】:

  • 我试过了,但还是不能玩。你能帮帮我吗?
【解决方案2】:

在尝试使用 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-22
    • 1970-01-01
    • 1970-01-01
    • 2020-02-29
    • 1970-01-01
    • 2021-10-27
    相关资源
    最近更新 更多