【问题标题】:Extract video portion from Live Photo从 Live Photo 中提取视频部分
【发布时间】:2016-01-02 18:44:30
【问题描述】:

有人知道如何从 Live Photo 中提取视频部分吗?我正在开发一个将 Live Photo 转换为 GIF 的应用程序,第一步是从 Live Photo 中获取视频文件。这似乎应该是可能的,因为如果您将手机插入 Mac,您可以看到单独的图像和视频文件。我在提取过程中遇到了一堵砖墙,我尝试了很多方法,但都失败了。

我做的第一件事是通过执行以下操作为我认为是 Live Photo 的视频部分的内容获取 PHAsset:

    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 {

将 PHAsset 转换为我尝试过的 AVAsset:

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

我认为这个不起作用,因为带有 duration.value 的调试打印给出了 0。 我也试过不加“.mov”,还是不行。

我也试过了:

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

并且 debugPrint(avAsset) 打印 nil 所以它不起作用。

我有点担心他们可能无法做到这一点,我好像在绕圈子,因为我得到的 PHAsset 似乎仍然是一张实时照片,而不是真正的视频。

【问题讨论】:

    标签: ios video avasset phasset phlivephoto


    【解决方案1】:

    使用PHAssetResourceManagerPHAssetResource 获取视频文件。

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

    注意:Live Photo 特定的 API 是在 iOS 9.1 中引入的

    【讨论】:

    • 这仅适用于 9.1,有更通用的解决方案吗?
    • 在 iOS 9.1 中引入了 Live Photo 特定的 API
    【解决方案2】:
    // 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
    }
    

    【讨论】:

    • fileURL 不是公共财产。我不确定它会有多稳定,或者我是否不会被应用商店拒绝。
    【解决方案3】:

    我不小心做到了。我有一个名为 Goodreader 的 ios 应用程序(可在应用程序商店中获得),它具有类似 Windows 的文件管理器。导入实时照片时,会将其保存为以 .pvt 结尾的文件夹,其中包含 jpg 和 mov 文件。只有一个警告:您需要在将实时照片发送给自己或其他人之后从消息应用程序中打开实时照片,才能看到“导入到 goodreader”选项,而不是从照片应用程序。

    【讨论】: