It's a good practice to handle errors from your code to get info about the problem so lets make next error handler:
class ErrorObserver: NSObject {
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
guard let player = object as? AVPlayer, let error = player.currentItem?.error, let keyPath = keyPath else {
return
}
print("Key:", keyPath)
print("Error:", error)
}
}
let errorObserver = ErrorObserver()
...
// Add observer AVPlayerItem status
player.addObserver(errorObserver, forKeyPath: #keyPath(AVPlayer.currentItem.status), options:[.new], context: nil)
If you run your code it produces next error:
Key: currentItem.status
Error: Error Domain=AVFoundationErrorDomain Code=-11850 "Operation Stopped" UserInfo={NSLocalizedFailureReason=The server is not correctly configured., NSLocalizedDescription=Operation Stopped, NSUnderlyingError=0x600003bbc060 {Error Domain=NSOSStatusErrorDomain Code=-12939 "(null)"}}
"The server is not correctly configured." is often related to the HTTP range requests issue on a server side because supporting downloading by ranges is required to play media from the Internet.
Lets check this with curl
:
$ curl -I https://ipfs.moralis.io:2053/ipfs/QmUjWnQZVVNmTSVak2QDhTxMkn3dPQozxawa1sm3jE5bLr
HTTP/2 200
date: Fri, 05 Aug 2022 09:48:23 GMT
content-type: video/mp4
content-length: 4835525
cf-ray: 735e9de8d95c9290-FRA
accept-ranges: bytes
...
As you can see from the response the server supports ranges - "accept-ranges: bytes".
Lets check the partial request:
$ curl https://ipfs.moralis.io:2053/ipfs/QmUjWnQZVVNmTSVak2QDhTxMkn3dPQozxawa1sm3jE5bLr -i -H "Range: bytes=0-1023"
HTTP/2 200
date: Fri, 05 Aug 2022 09:50:05 GMT
content-type: video/mp4
content-length: 4835525
cf-ray: 735ea066cfd61649-MUC
accept-ranges: bytes
...
The server responds with HTTP/2 200
and the full content length but the response must be like this:
HTTP/2 206 Partial Content
Accept-Ranges: bytes
Server: UploadServer
Aka-c-hit: cache-hit
Content-Range: bytes 0-1023/253755577
Content-Length: 1024
Connection: keep-alive
Content-Type: video/mp4
...
So that your server doesn't support HTTP ranges requests and AVPlayer can't play your mp4 video.
You can resolve the issue with two ways:
- Change the servers's settings to support HTTP range requests.
- Programmatically download video and save it to a local file and after you can play it from file URL.