我使用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()此流使用相当标准的auth流程进行保护:
对主清单的请求是使用附加的令牌查询参数进行的。对主清单的响应包括一个set-cookie头。在set-cookie响应标头上指定域的每个后续请求都包括其请求标头上的cookie。
我发现,通过委托发出的所有请求都会将cookie添加到标头中,但是由于委托不能用于TS段,所以没有添加cookie。
是否有人知道强制AVURLAsset始终使用对主清单的响应为在AVAssetResourceLoaderDelegate之外发出的请求提供的cookie头的方法?
因为我确实将URLResponse提供给AVAssetResourceLoadingRequest,并且我知道您可以使用URLSessionConfiguration的httpShouldAccpetCookies、httpCookieAcceptPolicy和httpCookieStorage属性向URLSession添加cookie。我不认为这是不可能的。
我还知道可以将AVURLAssetHTTPCookiesKey添加到AVURLAasset的实例化中,但在发出主清单请求之前,我没有cookie。
发布于 2018-05-10 15:25:40
苹果公司的回应:
不可能使用AVAssetResourceLoaderDelegate来捕获和修改HLS播放列表的主/子清单,以便为清单URL的域设置cookie头。目前在AVFoundation中不支持这一点。 当前对cookies的唯一支持是能够使用AVURLAsset AVURLAssetHTTPCookiesKey初始化选项来允许AVURLAsset为HTTP(S)请求使用附加HTTP。有关详细信息,请参阅https://developer.apple.com/reference/avfoundation/avurlassethttpcookieskey。 只需获取cookies并创建一个具有如下所示键值对的字典( @{AVURLAssetHTTPCookiesKey : cookies} ),然后在AVURLAsset URLAssetWithURL:linkUrl选项中指定此字典: NSArray *cookie= [NSHTTPCookieStorage sharedHTTPCookieStorage cookie]; AVURLAsset * asset = AVURLAsset URLAssetWithURL:yourURL选项:@{AVURLAssetHTTPCookiesKey: cookies}; AVPlayerItem * item = AVPlayerItem playerItemWithAsset:asset; AVPlayer *player = [AVPlayer alloc initWithPlayerItem:item]; 请注意,这只允许您在创建AVAsset时设置cookies,并且不能随后在稍后的时间对它们进行更改。 此外,正如文档中所讨论的,在HLS中,可能会向不同的路径或主机发出许多HTTP请求(例如,媒体、加密密钥、变量索引)。在这两种情况下,HTTP请求都会丢失任何不适用于AVURLAsset URL的cookie。 一个可能有效的“非官方”解决方案是通过反向代理传递回放请求,该代理将允许您拦截请求,添加标头,将其发送到真正的服务器,然后从响应中提取头,然后将其返回到AVPlayer。
https://stackoverflow.com/questions/50241559
复制相似问题