Search code examples
iosswiftphlivephoto

How to Get Video from a Live Photo in iOS


I'm trying to figure it out, but can't find any useful information. I only found this:

PHAssetResourceManager.defaultManager().writeDataForAssetResource(assetRes, 
toFile: fileURL, options: nil, completionHandler: 
{
     // Video file has been written to path specified via fileURL
}

but I'm ashamed to say I have no idea how to play it out. I've created a UIImagePickerController and loaded an Image from the Camera Roll.


Solution

  • Use this code to get the video from live photo:

    - (void)videoUrlForLivePhotoAsset:(PHAsset*)asset withCompletionBlock:(void (^)(NSURL* url))completionBlock{
        if([asset isKindOfClass:[PHAsset class]]){
            NSString* identifier = [(PHAsset*)asset localIdentifier];
            NSString* filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mov",[NSString stringWithFormat:@"%.0f",[[NSDate date] timeIntervalSince1970]]]];
            NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
    
            PHLivePhotoRequestOptions* options = [PHLivePhotoRequestOptions new];
            options.deliveryMode = PHImageRequestOptionsDeliveryModeFastFormat;
            options.networkAccessAllowed = YES;
            [[PHImageManager defaultManager] requestLivePhotoForAsset:asset targetSize:[UIScreen mainScreen].bounds.size contentMode:PHImageContentModeDefault options:options resultHandler:^(PHLivePhoto * _Nullable livePhoto, NSDictionary * _Nullable info) {
                if(livePhoto){
                    NSArray* assetResources = [PHAssetResource assetResourcesForLivePhoto:livePhoto];
                    PHAssetResource* videoResource = nil;
                    for(PHAssetResource* resource in assetResources){
                        if (resource.type == PHAssetResourceTypePairedVideo) {
                            videoResource = resource;
                            break;
                        }
                    }
                    if(videoResource){
                        [[PHAssetResourceManager defaultManager] writeDataForAssetResource:videoResource toFile:fileUrl options:nil completionHandler:^(NSError * _Nullable error) {
                            if(!error){
                                completionBlock(fileUrl);
                            }else{
                                completionBlock(nil);
                            }
                        }];
                    }else{
                        completionBlock(nil);
                    }
                }else{
                    completionBlock(nil);
                }
            }];
        }else{
            completionBlock(nil);
        }
    }
    

    Basically what you have to do is that you first need to fetch the PHLivePhoto object from your PHAsset. After that, you will have to traverse all the asset resources within your live photo and check if it is of type PHAssetResourceTypePairedVideo.

    If yes, you got your video. Now you will require to save it to some temporary directory as I did here and use this file for whatever purpose you may have.

    To Play this video, you can use the following code:

    NSURL *videoURL = [NSURL fileURLWithPath:fileUrl];
    AVPlayer *player = [AVPlayer playerWithURL:videoURL];
    AVPlayerViewController *playerViewController = [AVPlayerViewController new];
    playerViewController.player = player;
    [self presentViewController:playerViewController animated:YES completion:nil];
    

    Feel free to ask if you need any clarification.

    P.S.- I made a few changes in this method to remove dependency of my application's code so the above code is untested, however I feel it should work as expected.