Skip to content

Instantly share code, notes, and snippets.

@Ali72
Last active May 17, 2024 15:38
Show Gist options
  • Save Ali72/cbde769d4bbf55390c8dcfb97a81f6f4 to your computer and use it in GitHub Desktop.
Save Ali72/cbde769d4bbf55390c8dcfb97a81f6f4 to your computer and use it in GitHub Desktop.
AVPlayer CoreMedia Errors
/**
-NOTE:
After AVPlayerItem faces an error you can create CoreMedia Error from the underlying Error inside AVPlayerItem error.
With the `CoreMediaError` enum, you can convert errors to more readable ones,handle AVPlayerItem Common errors,
and show the proper messages to your users.
**/
public enum CoreMediaError:Error {
static let domain = "CoreMediaErrorDomain"
case unknown
case notFound
case unauthorized
case authenticationError
case forbidden
case unavailable
case mediaFileError
case bandwidthExceeded
case playlistUnchanged
case decoderMalfunction
case decoderTemporarilyUnavailable
case wrongHostIP
case wrongHostDNS
case badURL
case invalidRequest
case unrecognizedHttpResponse
init?(_ error:NSError){
guard error.domain == CoreMediaError.domain else {return nil}
switch error.code {
case -12937:
// HTTP: 401 -12937 CoreMediaErrorDomain Authentication Error
// HTTP: 407 -12937 CoreMediaErrorDomain Authentication Error
self = .authenticationError
case -16840:
self = .unauthorized
case -12660:
// HTTP: 403 -12660 CoreMediaErrorDomain HTTP 403: Forbidden
self = .forbidden
case -12938:
//HTTP: 404 -12938 CoreMediaErrorDomain HTTP 404: File not found
self = .notFound
case -12661:
//HTTP: 503 -12661 CoreMediaErrorDomain HTTP 503: Unavailable
self = .unavailable
case -12645, -12889:
// if long .ts video file respons -12645 CoreMediaErrorDomain No response for media file in 10 s
// https://developer.apple.com/forums/thread/5589
self = .mediaFileError
case -12318:
// video .ts file bitrate differ from m3u8 declaration -12318 CoreMediaErrorDomain Segment exceeds specified bandwidth for variant
self = .bandwidthExceeded
case -12642:
// for live stream.playlist m3u8 did not change too long -12642 CoreMediaErrorDomain Playlist File unchanged for 2 consecutive reads
self = .playlistUnchanged
case -12911:
self = .decoderMalfunction
case -12913:
self = .decoderTemporarilyUnavailable
case -1004:
// if wrong host ip -1004 kCFErrorDomainCFNetwork
self = .wrongHostIP
case -1003:
// if wrong dns host name -1003 kCFErrorDomainCFNetwork
self = .wrongHostDNS
case -1000:
// if bad formatted URL -1000 kCFErrorDomainCFNetwork
self = .badURL
case -1202:
// if invalid https/ssl request -1202 kCFErrorDomainCFNetwork
self = .invalidRequest
case -12666:
//400 -12666 CoreMediaErrorDomain unrecognized http response 400
//402 -12666 CoreMediaErrorDomain unrecognized http response 402
//405 -12666 CoreMediaErrorDomain unrecognized http response 405
//406 -12666 CoreMediaErrorDomain unrecognized http response 406
//409 -12666 CoreMediaErrorDomain unrecognized http response 409
//...
//415 -12666 CoreMediaErrorDomain unrecognized http response 415
//500 -12666 CoreMediaErrorDomain unrecognized http response 500
//501 -12666 CoreMediaErrorDomain unrecognized http response 501
//502 -12666 CoreMediaErrorDomain unrecognized http response 502
//504 -12666 CoreMediaErrorDomain unrecognized http response 504
//505 -12666 CoreMediaErrorDomain unrecognized http response 505
self = .unrecognizedHttpResponse
default:
self = .unknown
}
}
}
//Add an observer to your new AVPlayerItem before replacing it in AVPlayer
myAVPlayerItem.addObserver(self, forKeyPath: "status", options: .new, context: nil)
//Remove the observer from your old AVPlayerItem after replacing it with a new one
myAVPlayerItem.removeObserver(self, forKeyPath: "status")
//Observe AVPlayerItem status change
override open func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "status",let value = change?[.newKey] as? Int,
let status = AVPlayerItem.Status(rawValue: value),
let item = object as? AVPlayerItem {
if status == .failed,
let error = item.error as NSError?,
let underlyingError = error.userInfo[NSUnderlyingErrorKey] as? NSError {
if let coreMediaError = CoreMediaError(underlyingError){
//It's core media error
//You can handle it here
}
}
}
}
@lujiaqiooo
Copy link

Hello, i met the problem when playing with AVPlayer which the CoreMediaError code is -16839 ('Unable to get playlist before long download timer.').
Did you manage to find more informations about this?

@unferna
Copy link

unferna commented May 17, 2024

I also have this error code -12865 when trying to load the m3u8 file from the local storage. After some research, I read that you cannot do it because m3u8 files are meant to be asked from a server. So if as I was you're also trying to modify the M3U8 playlist to limit the available qualities for the user, let me warn you that don't waste your time because you can't do it.
I guess if you create an internal server using GCDWebServer maybe you can do something but I'm not sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment