Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Play Videos PHAsset in iOS?

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.

like image 438
Sazzad Hissain Khan Avatar asked Sep 06 '16 13:09

Sazzad Hissain Khan


Video Answer


4 Answers

After several days experiment finally I come upon a solution,

Import File

import AVKit 

From PHAsset

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()                 }             })         })     } 

From AppLocalUrl

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()             }         })     } 
like image 178
Sazzad Hissain Khan Avatar answered Sep 28 '22 07:09

Sazzad Hissain Khan


@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()         }     } } 
like image 31
YYamil Avatar answered Sep 28 '22 08:09

YYamil


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()
            }
        }
    }
}
like image 25
iCoder Avatar answered Sep 28 '22 07:09

iCoder


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()
                }
            }
        }
    }
like image 40
bhavik Avatar answered Sep 28 '22 06:09

bhavik