I want to play video from PHAsset
, collected from iOS Photos. PHAsset
video nsurl
(https://stackoverflow.com/a/35099857/1084174) is valid to my own application lets say MyPlayer
for few moments/blocks. When I am copying the image/video into MyPlayers
own sandbox only then the nsurl
becomes always valid. It seems to me,
I need to copy each video from temporary
PHAsset
nsurl to MyPlayers sandbox (appgroup/documents) and only then I can play the video with sandbox relative nsurl.
If this is the case how do all other player play long videos on the fly? If there is any other way to play video without copying to apps sandbox, please let me know the way.
After several days experiment finally I come upon a solution,
import AVKit
static func playVideo (view:UIViewController, asset:PHAsset) { guard (asset.mediaType == PHAssetMediaType.Video) else { print("Not a valid video media type") return } PHCachingImageManager().requestAVAssetForVideo(asset, options: nil, resultHandler: {(asset: AVAsset?, audioMix: AVAudioMix?, info: [NSObject : AnyObject]?) in let asset = asset as! AVURLAsset dispatch_async(dispatch_get_main_queue(), { let player = AVPlayer(URL: asset.URL) let playerViewController = AVPlayerViewController() playerViewController.player = player view.presentViewController(playerViewController, animated: true) { playerViewController.player!.play() } }) }) }
static func playVideo (view:UIViewController, appLocalUrl:NSURL) { dispatch_async(dispatch_get_main_queue(), { let player = AVPlayer(URL: appLocalUrl) let playerViewController = AVPlayerViewController() playerViewController.player = player view.presentViewController(playerViewController, animated: true) { playerViewController.player!.play() } }) }
@Sazzad Hissain Khan solution in Swift 3:
From PHAsset:
func playVideo (view: UIViewController, videoAsset: PHAsset) { guard (videoAsset.mediaType == .video) else { print("Not a valid video media type") return } PHCachingImageManager().requestAVAsset(forVideo: videoAsset, options: nil) { (asset, audioMix, args) in let asset = asset as! AVURLAsset DispatchQueue.main.async { let player = AVPlayer(url: asset.url) let playerViewController = AVPlayerViewController() playerViewController.player = player view.present(playerViewController, animated: true) { playerViewController.player!.play() } } } }
From AppLocalUrl:
func playVideo (view: UIViewController, appLocalUrl: URL) { DispatchQueue.main.async { let player = AVPlayer(url: appLocalUrl) let playerViewController = AVPlayerViewController() playerViewController.player = player view.present(playerViewController, animated: true) { playerViewController.player!.play() } } }
The below solution works for slow-motion videos as well.
func playVideo(asset: PHAsset) {
guard asset.mediaType == .video else {
// Handle if the asset is not a video.
return
}
let options = PHVideoRequestOptions()
options.isNetworkAccessAllowed = true
PHCachingImageManager().requestPlayerItem(forVideo: asset, options: options) { (playerItem, info) in
DispatchQueue.main.async {
let playerViewController = AVPlayerViewController()
playerViewController.player = AVPlayer(playerItem: playerItem)
present(playerViewController, animated: true) {
playerViewController.player?.play()
}
}
}
}
In Swift 5
func playVideo(view:UIViewController, asset:PHAsset) {
guard (asset.mediaType == PHAssetMediaType.video)
else {
print("Not a valid video media type")
return
}
PHCachingImageManager().requestAVAsset(forVideo: asset, options: nil) { (assets, audioMix, info) in
let asset = assets as! AVURLAsset
DispatchQueue.main.async {
let player = AVPlayer(url: asset.url)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
view.present(playerViewController, animated: true) {
playerViewController.player!.play()
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With