3

我正在使用AVAssetResourceLoadingDelegate拦截 HLS 清单的所有清单请求

let str = "examplehttp://example.com/path/to/master.m3u8?token=SOMETOKEN"
guard let url = URL(string: str) else { return }

let asset = AVURLAsset(url: url)
let loaderQueue = DispatchQueue(label: "com.example.LoaderQueue")
asset.resourceLoader.setDelegate(delegate, queue: loaderQueue)

let item = AVPlayerItem(asset: asset)

player = AVPlayer(playerItem: item)
player?.playImmediately(atRate: 1.0)

在委托中,我自己使用所有清单请求URLSession并将响应返回给AVAssetResourceLoadingRequest

// NOTE: dataRequest: AVAssetResourceLoadingDataRequest
dataRequest.respond(with: data)
loadingRequest.response = response
loadingRequest.finishLoading()

此流使用相当标准的身份验证过程进行保护:

对主清单的请求是使用附加的令牌查询参数发出的。对主清单的响应包括一个 set-cookie 标头。在 set-cookie 响应标头上指定域的每个后续请求都在其请求标头中包含 cookie。

我发现通过委托发出的所有请求都将 cookie 添加到标头中,但由于委托不能用于 TS 段,因此没有添加 cookie。

有谁知道一种方法来强制AVURLAsset始终使用对主清单的响应提供的 cookie 标头来处理在外部发出的请求AVAssetResourceLoaderDelegate

由于我确实提供了URLResponse支持,AVAssetResourceLoadingRequest并且我知道您可以使用 URLSessionConfiguration 的 、 和 属性将 cookie 添加httpShouldAccpetCookieshttpCookieAcceptPolicyURLSession httpCookieStorage。我不认为这超出了可能性范围。

我也知道AVURLAssetHTTPCookiesKey可以将其添加到实例化中,AVURLAasset但在发出主清单请求之前我没有 cookie。

4

1 回答 1

3

苹果的回应:

无法使用 AVAssetResourceLoaderDelegate 来捕获和修改 HLS 播放列表的主/子清单,以便为清单 URL 的域设置 cookie 标头。AVFoundation 目前不支持此功能。

[当前] 对 cookie 的唯一支持是能够使用 AVURLAsset AVURLAssetHTTPCookiesKey 初始化选项以允许 AVURLAsset 为 HTTP(S) 请求使用额外的 HTTP cookie。有关更多信息,请参阅 https://developer.apple.com/reference/avfoundation/avurlassethttpcookieskey

只需获取您的 cookie 并使用如下所示的键值对创建一个字典( @{AVURLAssetHTTPCookiesKey : cookies} ),然后在 AVURLAsset URLAssetWithURL:linkUrl 选项中指定此字典:

NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];

AVURLAsset * 资产 = [AVURLAsset URLAssetWithURL:yourURL 选项:@{AVURLAssetHTTPCookiesKey : cookies}];

AVPlayerItem * item = [AVPlayerItem playerItemWithAsset:asset];

AVPlayer *player = [[AVPlayer alloc] initWithPlayerItem:item];

请注意,这只允许您在创建 AVAsset 时设置 cookie,并且您不能在以后更改这些。

此外,正如文档中所讨论的,在 HLS 中,许多 HTTP 请求(例如,媒体、加密密钥、变体索引)可能会发送到不同的路径或主机。在这两种情况下,HTTP 请求都会丢失任何不适用于 AVURLAsset URL 的 cookie。

一种可能可行的“非官方”解决方案是通过反向代理传递播放请求,这将允许您拦截请求,添加标头,将其发送到真实服务器,然后从响应中提取标头,然后将其返回给影音播放器。

于 2018-05-10T15:25:40.533 回答