我使用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 httpShouldAccpetCookies
,httpCookieAcceptPolicy
添加Cookie到URLSession,以及httpCookieStorage
属性。我不认为这超出了可能性范围。
我也知道AVURLAssetHTTPCookiesKey
可以添加到AVURLAasset
的实例化中,但是在完成主清单请求之前我没有cookie。
答案 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之前,响应中的标题。