Поток HLS с использованием AVAssetResourceLoaderDelegate Фрагмент TS запрашивает отсутствующий заголовок cookie - PullRequest
0 голосов
/ 08 мая 2018

Я использую 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, и я знаю, что вы можете добавить куки в URLSession, используя свойства httpShouldAccpetCookies, httpCookieAcceptPolicy и httpCookieStorage URLSessionConfiguration. Я не думаю, что это выходит за рамки возможностей.

Мне также известно о AVURLAssetHTTPCookiesKey, который можно добавить к созданию экземпляра AVURLAasset, но у меня нет cookie, пока не будет сделан основной запрос манифеста.

1 Ответ

0 голосов
/ 10 мая 2018

Ответ от Apple:

Невозможно использовать AVAssetResourceLoaderDelegate для захвата и измените главный / дочерний манифест для списка воспроизведения HLS, чтобы установить заголовок cookie для домена URL-адреса манифеста. Это не в настоящее время поддерживается в AVFoundation.

[Единственная текущая поддержка файлов cookie - это возможность использовать AVURLAsset AVURLAssetHTTPCookiesKey опция инициализации, чтобы позволить AVURLAsset для использования дополнительных файлов cookie HTTP для запросов HTTP (S). Увидеть https://developer.apple.com/reference/avfoundation/avurlassethttpcookieskey для получения дополнительной информации.

Просто получите ваши куки и создайте словарь со значением ключа пары, как показано ниже (@ {AVURLAssetHTTPCookiesKey: cookies}), затем укажите этот словарь в AVURLAsset URLAssetWithURL: linkUrl опции:

NSArray * cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] печенье];

AVURLAsset * asset = [AVURLAsset URLAssetWithURL: yourURL параметры: @ {AVURLAssetHTTPCookiesKey: куки}];

AVPlayerItem * item = [AVPlayerItem playerItemWithAsset: asset];

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

Обратите внимание, что это позволяет вам устанавливать куки только когда AVAsset создан, и вы не сможете впоследствии изменить их позже.

Также, как обсуждалось в документации, в HLS много HTTP-запросов. (например, медиа, ключ шифрования, индекс варианта) могут быть выданы другим пути или хосты. В обоих этих случаях HTTP-запросы будут отсутствовать любые файлы cookie, которые не применяются к URL-адресу AVURLAsset.

Одним из "неофициальных" решений, которое может сработать, является передача воспроизведения. запрос через обратный прокси, который позволит вам перехватить запросить, добавить заголовки, отправить его на реальный сервер, а затем извлечь Заголовки ответа перед его возвратом в AVPlayer.

...