40

我正在将我们的应用程序转换为使用 iOS8 的照片框架,ALAsset 框架显然是 iOS8 下的二等公民。

我有一个问题是我们的架构真的需要一个 NSURL 来表示媒体在“磁盘”上的位置。我们使用它来将媒体上传到我们的服务器以进行进一步处理。

使用 ALAsset 很容易:

    ALAssetRepresentation *rep = [asset defaultRepresentation];
    self.originalVideo = rep.url;

但我只是没有在 PHAsset 中看到这种能力。我想我可以打电话:

    imageManager.requestImageDataForAsset

然后把它写到文件系统中的一个临时点,但这看起来非常沉重和浪费,更不用说可能很慢了。

有没有办法得到这个,或者我要重构我的应用程序,只使用 iOS7 的 NSURL 和 iOS8 的其他方法?

4

10 回答 10

24

如果您使用 [ imageManager requestAVAssetForVideo...],它将返回一个AVAsset. 那个 AVAsset 实际上是一个AVURLAsset,所以如果你转换它,你可以访问它的 -url属性。

我不确定您是否可以从中创建新资产,但它确实为您提供了位置。

于 2014-10-01T14:43:00.777 回答
19

SWIFT 2.0 版本 此函数从 PHAsset (图像和视频)返回 NSURL

func getAssetUrl(mPhasset : PHAsset, completionHandler : ((responseURL : NSURL?) -> Void)){

    if mPhasset.mediaType == .Image {
        let options: PHContentEditingInputRequestOptions = PHContentEditingInputRequestOptions()
        options.canHandleAdjustmentData = {(adjustmeta: PHAdjustmentData) -> Bool in
            return true
        }
        mPhasset.requestContentEditingInputWithOptions(options, completionHandler: {(contentEditingInput: PHContentEditingInput?, info: [NSObject : AnyObject]) -> Void in
            completionHandler(responseURL : contentEditingInput!.fullSizeImageURL)
        })
    } else if mPhasset.mediaType == .Video {
        let options: PHVideoRequestOptions = PHVideoRequestOptions()
        options.version = .Original
        PHImageManager.defaultManager().requestAVAssetForVideo(mPhasset, options: options, resultHandler: {(asset: AVAsset?, audioMix: AVAudioMix?, info: [NSObject : AnyObject]?) -> Void in

            if let urlAsset = asset as? AVURLAsset {
                let localVideoUrl : NSURL = urlAsset.URL
                completionHandler(responseURL : localVideoUrl)
            } else {
                completionHandler(responseURL : nil)
            }
        })
    }

}
于 2016-01-30T09:00:19.147 回答
9

如果您有 PHAsset,您可以像这样获取所述资产的 url:

[asset requestContentEditingInputWithOptions:editOptions
                           completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
    NSURL *imageURL = contentEditingInput.fullSizeImageURL;
}];
于 2015-03-05T17:33:40.153 回答
9

使用 PHObject 的新localIdentifier属性。(PHAsset 继承自此)。

它提供了与 ALAsset URL 类似的功能,即您可以通过调用方法来加载资产

+[PHAsset fetchAssetsWithLocalIdentifiers:identifiers options:options]
于 2015-04-29T04:19:47.090 回答
5

以上所有解决方案都不适用于慢动作视频。我发现处理所有视频资产类型的解决方案是:

func createFileURLFromVideoPHAsset(asset: PHAsset, destinationURL: NSURL) {
    PHCachingImageManager().requestAVAssetForVideo(self, options: nil) { avAsset, _, _ in
        let exportSession = AVAssetExportSession(asset: avAsset!, presetName: AVAssetExportPresetHighestQuality)!
        exportSession.outputFileType = AVFileTypeMPEG4
        exportSession.outputURL = destinationURL

        exportSession.exportAsynchronouslyWithCompletionHandler {
            guard exportSession.error == nil else {
                log.error("Error exporting video asset: \(exportSession.error)")
                return
            }

            // It worked! You can find your file at: destinationURL
        }
    }
}
于 2016-08-17T10:06:51.490 回答
3

在这里看到这个答案。

而这个在这里

根据我的经验,您需要先将资产导出到磁盘才能获得完全可访问/可靠的 URL。

上面链接的答案描述了如何做到这一点。

于 2016-03-16T19:50:35.890 回答
2

只想从@jlw 的评论中发布隐藏的宝石

@rishu1992 对于慢动作视频,获取 AVComposition 的 AVCompositionTrack(媒体类型为 AVMediaTypeVideo),获取其第一个片段(类型为 AVCompositionTrackSegment),然后访问其 sourceURL 属性。– jlw 2015 年 8 月 25 日在 11:52

于 2017-09-09T05:34:34.660 回答
1

在谈到来自 的 url 时PHAsset,我曾经在Swift 2上准备了一个 util func (尽管仅用于播放来自 的视频PHAsset)。在这个答案中分享它,可能会对某人有所帮助。

static func playVideo (view:UIViewController, asset:PHAsset)

请检查这个答案

于 2016-09-20T21:34:57.097 回答
1

这是一个方便的 PHAsset 类别:

@implementation PHAsset (Utils)

- (NSURL *)fileURL {
    __block NSURL *url = nil;

    switch (self.mediaType) {
        case PHAssetMediaTypeImage: {
            PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
            options.synchronous = YES;
            [PHImageManager.defaultManager requestImageDataForAsset:self
                                                            options:options
                                                      resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
                                                          url = info[@"PHImageFileURLKey"];
                                                      }];
            break;
        }
        case PHAssetMediaTypeVideo: {
            dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
            [PHImageManager.defaultManager requestAVAssetForVideo:self
                                                          options:nil
                                                    resultHandler:^(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info) {
                                                        if ([asset isKindOfClass:AVURLAsset.class]) {
                                                            url = [(AVURLAsset *)asset URL];
                                                        }
                                                        dispatch_semaphore_signal(semaphore);
                                                    }];
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            break;
        }
        default:
            break;
    }
    return url;
}

@end
于 2017-12-06T01:14:58.537 回答
0

我对视频文件有类似的问题,对我有用的是:

NSString* assetID = [asset.localIdentifier substringToIndex:(asset.localIdentifier.length - 7)];
NSURL* videoURL = [NSURL URLWithString:[NSString stringWithFormat:@"assets-library://asset/asset.mov?id=%@&ext=mov", assetID]];

其中资产是 PHAsset。

于 2016-08-17T17:36:20.243 回答