我正在将我们的应用程序转换为使用iOS8的照片框架,ALAsset框架显然是iOS8下的二等公民。
我遇到的问题是,我们的体系结构确实需要一个NSURL来表示媒体在"磁盘"上的位置。我们使用它将媒体上传到服务器进行进一步处理。
这对ALAsset:来说很容易
ALAssetRepresentation *rep = [asset defaultRepresentation];
self.originalVideo = rep.url;
但我只是在PHAsset中看不到这种能力。我想我可以打电话给
imageManager.requestImageDataForAsset
然后把它写到文件系统中的一个临时位置,但这看起来非常沉重和浪费,更不用说可能很慢了。
有没有办法做到这一点,或者我要重构更多的应用程序,只对iOS7使用NSURL,对iOS8使用其他方法?
如果使用[imageManager
requestAVAssetForVideo
…],它将返回一个AVAsset
。该AVAsset实际上是一个AVURLAsset
,所以如果对其进行强制转换,则可以访问它的-url
属性。
我不确定你是否能从中创建一个新的资产,但它确实给了你位置。
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)
}
})
}
}
如果你有一个PHAsset,你可以获得所述资产的url,如下所示:
[asset requestContentEditingInputWithOptions:editOptions
completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
NSURL *imageURL = contentEditingInput.fullSizeImageURL;
}];
使用PHObject的新localIdentifier
属性。(PHAsset继承自此)。
它提供了与ALAsset URL类似的功能,即您可以通过调用方法来加载资产
+[PHAsset fetchAssetsWithLocalIdentifiers:identifiers options:options]
以上所有解决方案都不适用于慢动作视频。我发现一个处理所有视频资产类型的解决方案是:
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
}
}
}
请在此处查看此答案。
还有这个。
根据我的经验,您需要首先将资产导出到磁盘,以便获得完全可访问/可靠的URL。
链接到上面的答案描述了如何做到这一点。
只想从@jlw 的评论中发布隐藏的宝石
@rishu1992对于slo-mo视频,请获取AVComposition的AVCompositionTrack(属于mediaType AVMediaTypeVideo),获取其第一个段(类型为AVCompositionTrackSegment),然后访问其sourceURL属性。–jlw 2015年8月25日11:52
在PHAsset
的url拼写中,我曾经在Swift 2上准备了一个util函数(尽管仅用于播放PHAsset
的视频)。在这个答案中分享它,可能会对某人有所帮助。
static func playVideo (view:UIViewController, asset:PHAsset)
请检查此答案
这里有一个方便的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
我对视频文件也有类似的问题,对我有效的是:
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。