AVPlayer with resourceLoader delegate get data but not playing video

Hello friends! The question actually duplicates this post: https://stackoverflow.com/questions/64512330/avplayer-with-resourceloader-delegate-get-data-but-not-playing-video

My task is to play a video from a repository that requires a certificate. If I use a simple AVPlayer setup without setting a AVAssetResourceLoaderDelegate:

Code Block
controller.player = AVPlayer(url: urlFromUnprotectedPlace)


the player perfectly opens urls from the unprotected storage and plays the video. But on trying to play video from a protected folder, it gives an error: "The certificate for this server is invalid". This problem is solved by setting a resourceLoader delegate:

Code Block
let asset = AVURLAsset(url: customSchemeUrl)
asset.resourceLoader.setDelegate(myDelegate, queue: .main)
let item = AVPlayerItem(asset: asset)
controller.player = AVPlayer(playerItem: item)

And the delegate method itself:
Code Block
func resourceLoader(
_ resourceLoader: AVAssetResourceLoader,
shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest
) -> Bool {
guard let url = url else {
logger.log("nil url")
return false
}
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("bytes=0-", forHTTPHeaderField: "Range")
let sessionTask = urlSession?.dataTask(with: request) { [weak self] data, response, error in
if let error = error {
self?.logger.log(error.localizedDescription)
return
}
loadingRequest.contentInformationRequest?.contentType = AVFileType.mp4.rawValue
loadingRequest.contentInformationRequest?.isByteRangeAccessSupported = true
loadingRequest.response = response
if let data = data {
loadingRequest.contentInformationRequest?.contentLength = Int64(data.count)
loadingRequest.dataRequest?.respond(with: data)
}
loadingRequest.finishLoading()
}
sessionTask?.resume()
return true
}

The data and the response come, the error is nil. The data is of the correct size. The response contains the status 206. The player's item has an observer of its state, but no one displays any errors - the player is just black and the download wheel is spinning.

But I went further. There is such a project: https://github.com/2ZGroupSolutionsArticles/Article_EZ002
I replaced my delegate with his delegate - identical behavior. But it also has the saving of the downloaded data to a local file. So, if after the completion of saving try to play this file - everything is OK, it is played.

My SwiftUI player:

Code Block
final class MyVideoPlayer: UIViewControllerRepresentable {
private let controller = AVPlayerViewController()
private var playerItemObserver: MyPlayerItemStateObserver?
private var resourceLoaderDelegate: EugeneResourceLoaderDelegate?
private var playingStarted = false
init(url: URL?) {
guard let url = url else { return }
resourceLoaderDelegate = EugeneResourceLoaderDelegate(withURL: url)
resourceLoaderDelegate?.completion = downloadCompletion()
controller.player = createPlayer()
}
func makeUIViewController(context: Context) -> AVPlayerViewController {
controller
}
func updateUIViewController(_ uiViewController: AVPlayerViewController, context: Context) {}
func play() -> some View {
playingStarted = true
controller.player?.play()
return self
}
}
extension MyVideoPlayer {
private func createPlayer() -> AVPlayer? {
guard
let delegate = resourceLoaderDelegate,
let streamingUrl = delegate.streamingAssetURL
else {
return nil
}
let asset = AVURLAsset(url: streamingUrl)
asset.resourceLoader.setDelegate(delegate, queue: .main)
playerItemObserver = MyPlayerItemStateObserver(asset: asset, logger: logger)
if let item = playerItemObserver?.item {
return AVPlayer(playerItem: item)
}
return nil
}
private func downloadCompletion() -> (URL?) -> Void {
{ [weak self] localFileURL in
guard let self = self else { return }
guard let localFileURL = localFileURL else {
print("Failed to download media file.")
return
}
print("Media file saved to: \(localFileURL)")
let status = self.controller.player?.timeControlStatus
if self.playingStarted && status?.rawValue == 1 {
self.controller.player = AVPlayer(url: localFileURL)
self.controller.player?.play()
}
}
}
}

I think I'm already out of ideas. I would be grateful for any help.

Upd. I printed out the state of the player and its currentItem before re-creating it to play the local file, and I got this:

Code Block
player?.reasonForWaitingToPlay - AVPlayerWaitingWhileEvaluatingBufferingRateReason
player?.currentItem?.isPlaybackBufferEmpty - true
player?.currentItem?.duration - value: 0


AVPlayer with resourceLoader delegate get data but not playing video
 
 
Q