Я пытаюсь воспроизвести видео с помощью AVPlayer, который был загружен внутри AVAssetResourceLoaderDelegate, но у меня всегда появляется пустой экран, и видео никогда не воспроизводится.
Это код:
let asset = AVURLAsset(url: URL(string: "fakescheme://video.mp4")!)
asset.resourceLoader.setDelegate(ResourceLoaderDelegate(), queue: DispatchQueue.main)
let item = AVPlayerItem(asset: asset)
let player = AVPlayer(playerItem: item)
let playerLayer = AVPlayerLayer(player: self.player)
playerLayer!.frame = self.view.bounds;
self.view.layer.addSublayer(self.playerLayer!)
player!.play()
...
class ResourceLoaderDelegate: NSObject, AVAssetResourceLoaderDelegate, URLSessionDelegate, URLSessionDataDelegate, URLSessionTaskDelegate {
public func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource resourceLoadingRequest: AVAssetResourceLoadingRequest) -> Bool {
var newRequest = URLRequest(url: URL(string: "https://example.com/video.mp4")!)
newRequest.allHTTPHeaderFields = resourceLoadingRequest.request.allHTTPHeaderFields
let sessionTask = URLSession.shared.dataTask(with: newRequest) { data, response, error in
resourceLoadingRequest.contentInformationRequest?.contentType = "video/mp4"
resourceLoadingRequest.contentInformationRequest?.isByteRangeAccessSupported = true
resourceLoadingRequest.contentInformationRequest?.contentLength = Int64(data.count)
resourceLoadingRequest.response = response
resourceLoadingRequest.dataRequest?.respond(with: data)
resourceLoadingRequest.finishLoading()
}
sessionTask.resume()
return true
}
}
Это базовая c идея:
fakescheme: // вызывает вызов делегата resourceLoader (), внутри него делается новый HTTP-запрос для загрузки реального видео.
И затем он вызывает resourceLoadingRequest.dataRequest? .respond (with: data), который должен был заставить AVPlayer воспроизводить загруженное видео. Переменная данных заполнена правильно, но я всегда получаю черный экран.
Видеофайл также в порядке, он воспроизводится, если я передаю его непосредственно в AVURLAsset ().
Я попытался миллион вещей и комбинаций, но не может заставить его играть, используя делегата. Любая помощь будет принята с благодарностью!
РЕДАКТИРОВАТЬ: Я добавлю еще немного информации.
Я попытался сделать это с зашифрованным видео AES, где используются 3 файла - .m3u8, ключ шифрования и .ts видео. Мне удалось заставить его загрузить .m3u8 и ключ с помощью делегата, но снова, когда я пытаюсь сделать это с видеофайлом, я получаю черный экран.
Это заставляет меня думать, что это может потребовать загрузки случиться по частям, но я не уверен, как правильно это сделать. Я также не могу найти какую-либо документацию по этому поводу, например, - если вы установите заголовки HTTP, как если бы они исходили от веб-сервера, если вы установили contentInformationRequest, et c. Делегат вызывается 2 раза:
// first time:
resourceLoadingRequest.dataRequest!.requestedLength == 2,
resourceLoadingRequest.dataRequest!.requestsAllDataToEndOfResource == false
// second time:
resourceLoadingRequest.dataRequest!.requestedLength == MAX_INT,
resourceLoadingRequest.dataRequest!.requestsAllDataToEndOfResource == true
Я не уверен, что с этим делать - я даю видео целиком оба раза, но безуспешно.