Подтвердить что ты не робот

NSURL от PHAsset

Я конвертирую наше приложение, чтобы использовать Рамки фотографий iOS8, структура ALAsset явно является гражданином второго класса в iOS8.

У меня проблема: наша архитектура действительно хочет, чтобы NSURL представлял местоположение носителя на "диске". Мы используем это для загрузки медиа на наши серверы для дальнейшей обработки.

Это было легко с помощью ALAsset:

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

Но я просто не вижу эту способность в PHAsset. Думаю, я могу позвонить:

    imageManager.requestImageDataForAsset

а затем записать его в временное место в файловой системе, но это кажется ужасно тяжелым и расточительным, не говоря уже о потенциально медленном.

Есть ли способ получить это или у меня будет рефакторинг большего количества моего приложения, чтобы использовать только NSURL для iOS7 и какой-то другой метод для iOS8?

4b9b3361

Ответ 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