Extract video portion from Live Photo
Asked Answered
L

3

11

Has anyone figured out how to extract the video portion from a Live Photo? I'm working on an app to convert Live Photos into a GIF, and the first step is to get the video file from the Live Photo. It seems like it should be possible, because if you plug in your phone to a Mac you can see the separate image and video files. I've kinda run into a brick wall in the extraction process, and I've tried many ways to do it and they all fail.

The first thing I did was obtain a PHAsset for what I think is the video part of the Live Photo, by doing the following:

    if let livePhoto = info["UIImagePickerControllerLivePhoto"] as? PHLivePhoto {
        let assetResources = PHAssetResource.assetResourcesForLivePhoto(livePhoto)
        for assetRes in assetResources {
            if (assetRes.type == .PairedVideo) {
                let assets = PHAsset.fetchAssetsWithLocalIdentifiers([assetRes.assetLocalIdentifier], options: nil)
                if let asset = assets.firstObject as? PHAsset {

To convert the PHAsset to an AVAsset I've tried:

    asset.requestContentEditingInputWithOptions(nil, completionHandler: { (contentEditingInput, info) -> Void in

        if let url = contentEditingInput?.fullSizeImageURL {
            let movieUrl = url.absoluteString + ".mov"
            let avAsset = AVURLAsset(URL: NSURL(fileURLWithPath: movieUrl), options: nil)
            debugPrint(avAsset)
            debugPrint(avAsset.duration.value)
        }
    })

I don't think this one works because the debug print with the duration.value gives 0. I've also tried without the ".mov" addition and it still doesn't work.

I also tried:

    PHImageManager.defaultManager().requestAVAssetForVideo(asset, options: nil, resultHandler: { (avAsset, audioMix, info) -> Void in
        debugPrint(avAsset)
    })

And the debugPrint(avAsset) prints nil so it doesn't work.

I'm kind of afraid they might have made it impossible to do, it seems like I'm going in circles since it seems like the PHAsset I got is still a Live Photo and not actually a video.

Leeleeann answered 6/10, 2015 at 0:37 Comment(0)
C
17

Use the PHAssetResourceManager to get the video file from the PHAssetResource.

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

NOTE: The Live Photo specific APIs were introduced in iOS 9.1

Capable answered 7/10, 2015 at 6:39 Comment(2)
This works only with 9.1, Have more general solution?Formalize
The Live Photo specific APIs were introduced in iOS 9.1Capable
M
0
// suppose you have PHAsset instance (you can get it via [PHAsset fetchAssetsWithOptions:...])

PHAssetResource *videoResource = nil;
NSArray *resourcesArray = [PHAssetResource assetResourcesForAsset:asset];

const NSInteger livePhotoAssetResourcesCount = 2;
const NSInteger videoPartIndex = 1;

if (resourcesArray.count == livePhotoAssetResourcesCount) {
   videoResource = resourcesArray[videoPartIndex];
}

if (videoResource) {
   NSString * const fileURLKey = @"_fileURL";
   NSURL *videoURL = [videoResource valueForKey:fileURLKey];

   // load video url using AVKit or AVFoundation
}
Mystique answered 6/2, 2017 at 13:8 Comment(1)
fileURL isn't a public property. I'm not certain how stable it will be, or if I won't get an app store rejection.Doxia
D
-2

I accidentally did. I have an ios app called Goodreader (available in the appstore) which features a windows-like file manager. When importing a live photo, it will save it as a folder ending in .pvt containing the jpg and mov files in it. There is only one caveat: you need to open the live photo from within the messages app after you've sent it to yourself or somebody else to see the "import to goodreader" option, not from the photos app.

Daughterinlaw answered 13/10, 2016 at 23:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.