swift - HLS 流使用 AVAssetResourceLoaderDelegate TS 片段请求缺少 Cookie header

标签 swift avfoundation http-live-streaming avassetresourceloaderdelegate

我正在使用 AVAssetResourceLoadingDelegate 来拦截对 HLS list 的所有 list 请求

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)

在委托(delegate)中,我自己使用 URLSession 执行所有 list 请求,并将响应返回给 AVAssetResourceLoadingRequest

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

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

对主 list 的请求是使用附加的 token 查询参数进行的。对主 list 的响应包括一个 set-cookie header 。在 set-cookie 响应 header 上指定域的每个后续请求都在其请求 header 中包含 cookie。

我发现,通过委托(delegate)发出的所有请求都将 cookie 添加到 header ,但由于委托(delegate)不能用于 TS 段,因此未添加 cookie。

有没有人知道一种方法可以强制 AVURLAsset 始终对在 AVAssetResourceLoaderDelegate 之外发出的请求使用由对主 list 的响应提供的 cookie header ?

由于我确实将 URLResponse 提供回 AVAssetResourceLoadingRequest 并且我知道您可以使用 URLSessionConfiguration 的 httpShouldAccpetCookies 向 URLSession 添加 cookie,httpCookieAcceptPolicyhttpCookieStorage 属性。我不认为这超出了可能性范围。

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

最佳答案

苹果的回应:

It is not possible to use the AVAssetResourceLoaderDelegate to capture and modify the master/child manifests for an HLS playlist to set a cookie header for the domain of the manifest URL. This is not currently supported in AVFoundation.

[The] only current support for cookies is the ability to use the AVURLAsset AVURLAssetHTTPCookiesKey initialization option to allow the AVURLAsset to use additional HTTP cookies for HTTP(S) requests. See https://developer.apple.com/reference/avfoundation/avurlassethttpcookieskey for more information.

Simply get your cookies and create a dictionary with the key value pairs as shown below ( @{AVURLAssetHTTPCookiesKey : cookies} ), then specify this dictionary in the AVURLAsset URLAssetWithURL:linkUrl options:

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

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

AVPlayerItem * item = [AVPlayerItem playerItemWithAsset:asset];

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

Please note this only allows you to set cookies when the AVAsset is created, and you can't then subsequently mutate these at a later time.

Also, as discussed in the documentation, in HLS, many HTTP requests (e.g., media, crypt key, variant index) might be issued to different paths or hosts. In both of these cases, HTTP requests will be missing any cookies that do not apply to the AVURLAsset URL.

One "unofficial" solution that might work is to pass the playback request through a reverse proxy which will allow you to intercept the request, add headers, send it to the real server, and then extract the headers from the response before returning it to the AVPlayer.

关于swift - HLS 流使用 AVAssetResourceLoaderDelegate TS 片段请求缺少 Cookie header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50241559/

相关文章:

Swift - 旋转图像,然后放大并裁剪以保持宽度/高度纵横比不变

ios - 调用 "didSelectItemAt"时从单元格内调用函数

iOS swift : nil IBOutlets with custom ViewController

ios无尽的视频录制

amazon-s3 - 如何以安全的方式从 S3 提供 HLS 流(授权和认证)

crash - WP8.1 (0xc0000005) 'Access violation' 崩溃

ios - 无法快速转换 json 数据

ios - 仅在铃声/静音开关打开时播放声音

ios - 更改assetVideoTrack的preferredTransform以解决合并视频时的镜像问题

youtube - YouTube 直播是否支持 HLS(HTTP 直播)?