Getting url for PHAsset

22,175

Solution 1

You should use PHImageManager.

Use the class's sharedInstance and call this method with your PHAsset, options, and a completion block handler:

- (PHImageRequestID)requestAVAssetForVideo:(PHAsset *)asset options:(PHVideoRequestOptions *)options resultHandler:(void (^)(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info))resultHandler

The handler will give you an AVAsset you should use for your AVPlayerItem, as opposed to a URL.

Example:

[[PHImageManager defaultManager] requestAVAssetForVideo:asset options:nil resultHandler:^(AVAsset *avAsset, AVAudioMix *audioMix, NSDictionary *info) {
  // Use the AVAsset avAsset
  AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:avAsset];
  AVPlayer *videoPlayer = [AVPlayer playerWithPlayerItem:playerItem];
}];

Beware its likely asynchronous which will interfere with your application flow further.

Solution 2

By the way, if you want the actual URL--that is to say, the same one that UIImagePickerController passes to an AVPlayerItem when it is created, and the same one that looks like the URL one would use with AVAssetReader/Writer--then do this:

[[PHImageManager defaultManager] requestAVAssetForVideo:phAsset options:nil resultHandler:^(AVAsset *avAsset, AVAudioMix *audioMix, NSDictionary *info) {
    NSURL *url = (NSURL *)[[(AVURLAsset *)avAsset URL] fileReferenceURL];
    NSLog(@"url = %@", [url absoluteString]);
    NSLog(@"url = %@", [url relativePath]);
 }];

Whereas phAsset is the PHAsset object, and avAsset is the resulting AVAsset object generated by PHImageManager, the output to the console from the above code will produce, for example:

2016-04-16 01:15:40.155 ChromaEpsilon[3423:933358] url = file:///.file/id=16777218.8262005
2016-04-16 01:15:40.155 ChromaEpsilon[3423:933358] url = /private/var/mobile/Media/DCIM/108APPLE/IMG_8421.MOV

Solution 3

Proper answer of @HirenPanchal in Swift 4.0(also working in Swift 5.0+) and iOS 9.0+

func getUrlFromPHAsset(asset: PHAsset, callBack: @escaping (_ url: URL?) -> Void)
{
    asset.requestContentEditingInput(with: PHContentEditingInputRequestOptions(), completionHandler: { (contentEditingInput, dictInfo) in

        if let strURL = (contentEditingInput!.audiovisualAsset as? AVURLAsset)?.url.absoluteString
        {
            PRINT("VIDEO URL: \(strURL)")
            callBack(URL.init(string: strURL))
        }
    })
}

Solution 4

For Swift 3.0 You can get string url for image and video from PHAsset object

asset.requestContentEditingInput(with: PHContentEditingInputRequestOptions(), completionHandler: { (contentEditingInput, dictInfo) in

    if asset.mediaType == .image
    {
      if let strURL = contentEditingInput?.fullSizeImageURL?.absoluteString
      {
         print("IMAGE URL: ", strURL)
      }
    }
    else
    {
      if let strURL = (contentEditingInput!.avAsset as? AVURLAsset)?.url.absoluteString
      {
         print("VIDEO URL: ", strURL)
      }
    }
  })

Solution 5

Get video URL from PHAsset in Swift 4.2 from didFinishPickingAssets in QBImagePickerController

let imagePicker = QBImagePickerController()
imagePicker.delegate = self
imagePicker.numberOfColumnsInPortrait = 2
imagePicker.maximumNumberOfSelection = 2
imagePicker.allowsMultipleSelection = true
imagePicker.mediaType = .video
        
self.present(imagePicker, animated: true, completion: nil)

func qb_imagePickerController(_ imagePickerController: 
QBImagePickerController!, didFinishPickingAssets assets: [Any]!) {
    for asset in assets
    {
        PHCachingImageManager().requestAVAsset(forVideo: asset as! PHAsset, 
        options: nil, resultHandler: {(asset, audioMix, info) -> Void in
            if asset != nil {
                let avasset = asset as! AVURLAsset
                let urlVideo = avasset.url
                yourarray.add(urlVideo as URL)
            }
            
        })

    }

    
    imagePickerController.dismiss(animated: true) {
         //You can access video urls here
         print("Total Videos:\(yourarray.count)")
    }
    
 }
Share:
22,175
Tom Fox
Author by

Tom Fox

Aspiring entrepreneur, Apple WWDC 2015 Scholarship recipient, hobbyist iOS developer, Parse Platform fan & contributor.

Updated on July 09, 2022

Comments

  • Tom Fox
    Tom Fox almost 2 years

    I am using a custom image picker to pick a time lapse and I want to get the url of the picked time lapse so I can then play the time lapse.

    - (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didFinishPickingAssets:(NSArray *)assets {
    for (PHAsset *asset in assets) {
    
    
    
        NSURL *url = [NSURL URLWithString: assetURLgoesHere];
        AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil];
        AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:avAsset];
        AVPlayer *videoPlayer = [AVPlayer playerWithPlayerItem:playerItem];
    
    
        [videoPlayer play];
    
    }
    
    [self dismissViewControllerAnimated:YES completion:NULL];
    }
    

    This is what I have at the moment but I need to get the url of the asset.

    I usually use swift but this custom image picker is written in objective-c. so I am a bit of a objective-c noob

    Updated code

    - (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didFinishPickingAssets:(NSArray *)assets {
    for (PHAsset *asset in assets) {
    
        - (PHImageRequestID)requestAVAssetForVideo:(PHAsset *)asset options:(PHVideoRequestOptions *)options resultHandler:(void (^)(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info))resultHandler
    
        NSURL *url = [NSURL URLWithString: asset];
        AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil];
        AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:avAsset];
        AVPlayer *videoPlayer = [AVPlayer playerWithPlayerItem:playerItem];
    
    
        [videoPlayer play];
    
    }
    
    [self dismissViewControllerAnimated:YES completion:NULL];
    }
    
  • Tom Fox
    Tom Fox over 8 years
    I tried this but i am not sure where to put this code. I tried putting it after did finish picking with assets but then I get an error. I really have next to no objective-c experience
  • Andrew
    Andrew over 8 years
    Please add your updated code to your question so I can take a look @TomFox
  • Andrew
    Andrew over 8 years
    When I said to 'call' the method, I meant that you should use [[PHImageManager sharedInstance] requestAVAssetForVideo...] @TomFox , sorry for any confusion. I didn't have a complete code snippet handy with its use so I just put the method declaration from the docs in my answer
  • Andrew
    Andrew over 8 years
    I added an example. See this also.
  • Ankit Kumar Gupta
    Ankit Kumar Gupta almost 7 years
    Can u please give a swift 3 version for this.