NSURL от PHAsset
Я конвертирую наше приложение, чтобы использовать Рамки фотографий iOS8, структура ALAsset явно является гражданином второго класса в iOS8.
У меня проблема: наша архитектура действительно хочет, чтобы NSURL представлял местоположение носителя на "диске". Мы используем это для загрузки медиа на наши серверы для дальнейшей обработки.
Это было легко с помощью ALAsset:
ALAssetRepresentation *rep = [asset defaultRepresentation];
self.originalVideo = rep.url;
Но я просто не вижу эту способность в PHAsset. Думаю, я могу позвонить:
imageManager.requestImageDataForAsset
а затем записать его в временное место в файловой системе, но это кажется ужасно тяжелым и расточительным, не говоря уже о потенциально медленном.
Есть ли способ получить это или у меня будет рефакторинг большего количества моего приложения, чтобы использовать только NSURL для iOS7 и какой-то другой метод для iOS8?
Ответы
Ответ 1
Если вы используете [ imageManager
requestAVAssetForVideo
...], он вернет AVAsset
. Этот AVAsset на самом деле является AVURLAsset
, поэтому, если вы его используете, вы можете получить к нему доступ - url
.
Я не уверен, что вы можете создать новый актив из этого, но он дает вам местоположение.
Ответ 2
версия SWIFT 2.0
Эта функция возвращает NSURL из PHAsset (изображение и видео)
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)
}
})
}
}
Ответ 3
Если у вас есть PHAsset, вы можете получить URL для указанного актива следующим образом:
[asset requestContentEditingInputWithOptions:editOptions
completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
NSURL *imageURL = contentEditingInput.fullSizeImageURL;
}];
Ответ 4
Используйте новый localIdentifier
свойство PHObject. (PHASset наследует от этого).
Он предоставляет аналогичную функциональность URL-адресу ALAsset, а именно, что вы можете загружать активы, вызывая метод
+[PHAsset fetchAssetsWithLocalIdentifiers:identifiers options:options]
Ответ 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
}
}
}
Ответ 6
Смотрите этот ответ здесь.
И этот здесь.
По моему опыту вам нужно сначала экспортировать актив на диск, чтобы получить полностью доступный/надежный URL.
Ответы, приведенные выше, описывают, как это сделать.
Ответ 7
При отображении url из PHAsset
, я когда-то подготовил функцию util на Swift 2 (хотя и для воспроизведения видео с PHAsset
). Совместное использование этого ответа может помочь кому-то.
static func playVideo (view:UIViewController, asset:PHAsset)
Пожалуйста, проверьте этот Ответ
Ответ 8
Просто хочу опубликовать скрытый камень из комментария от @jlw
@rishu1992 Для slo-mo видео, возьмите AVComposition AVCompositionTrack (из mediaType AVMediaTypeVideo), возьмите свой первый сегмент (типа AVCompositionTrackSegment), а затем получить доступ к его свойство sourceURL. - jlw Aug 25 '15 в 11:52
Ответ 9
У меня была аналогичная проблема с видеофайлами, что для меня работало:
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.
Ответ 10
Здесь удобная категория 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