Reputation: 3490
I am trying to play a video after I download from remote using following code.
let player = AVPlayer(url: URL(dataRepresentation: VideoService.instance.videoInfoArray[0].video, relativeTo: nil)!)
let playerController = AVPlayerViewController()
playerController.player = player
present(playerController, animated: true) {
player.play()
}
My VideoService class is a singleton class and video variable type is Data()
. However when I try to play video with below code it is not working. How can I play video using data representative?
Upvotes: 2
Views: 6027
Reputation: 6992
According to URL class documentation the initializer init?(dataRepresentation:relativeTo:isAbsolute:)
takes Data
argument, yes, but that data is supposed to be an ASCII representation of an URL string, not the actual data you want to play.
What you need to do is save your video data to a file and use the file's URL to initialize AVPlayer
guard let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)?.first else { return }
url.appendPathComponent("video.mpeg") // or whatever extension the video is
VideoService.instance.videoInfoArray[0].video.write(to: url) // assuming video is of Data type
let player = AVPlayer(url: url)
// other stuff with the player
To determine the reason why the player can't play your file, use key-value observing of player's status
property. If you observe a change to AVPlayer.Status.failed
, then you can check the player's error
property to see the localized reason and error code.
var playerStatusContext = 0
player.addObserver(player, forKeyPath: "status", options: [.new, .initial], context: &playerStatusContext)
// (...)
override func observeValue(forKeyPath keyPath: String?,
of object: Any?,
change: [NSKeyValueChangeKey : Any]?,
context: UnsafeMutableRawPointer?) {
// Only handle observations for the playerItemContext
guard context == &playerStatusContext else {
super.observeValue(forKeyPath: keyPath,
of: object,
change: change,
context: context)
return
}
if keyPath == #keyPath(AVPlayer.status) {
let status: AVPlayer.Status
if let statusNumber = change?[.newKey] as? NSNumber {
status = AVPlayer.Status(rawValue: statusNumber.intValue)!
} else {
status = .unknown
}
if status == .failed {
print(player.error)
}
}
}
Upvotes: 5