HLS流使用AVAssetResourceLoaderDelegate TS片段请求缺少Cookie标头

时间:2018-05-08 20:10:57

标签: swift avfoundation http-live-streaming avassetresourceloaderdelegate

我使用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 httpShouldAccpetCookieshttpCookieAcceptPolicy添加Cookie到URLSession,以及httpCookieStorage属性。我不认为这超出了可能性范围。

我也知道AVURLAssetHTTPCookiesKey可以添加到AVURLAasset的实例化中,但是在完成主清单请求之前我没有cookie。

1 个答案:

答案 0 :(得分:1)

Apple的回应:

  

无法使用AVAssetResourceLoaderDelegate进行捕获   并修改HLS播放列表的主/子清单以设置a   清单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]   饼干];

     

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

     

AVPlayerItem * item = [AVPlayerItem playerItemWithAsset:asset];

     

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

     

请注意,这只允许您在AVAsset时设置Cookie   创建,然后你不能随后在以后改变它们。

     

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

     

可能有效的一个“非官方”解决方案是传递回放   请求通过反向代理,允许你拦截   请求,添加标头,将其发送到真实服务器,然后解压缩   返回到AVPlayer之前,响应中的标题。