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
PHAssetnsurl 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