web-dev-qa-db-ja.com

PHAssetのNSURL

IOS8のPhotos Frameworkを使用するようにアプリを変換しています。ALAssetフレームワークは明らかにiOS8の二流の市民です。

私が問題を抱えているのは、私たちのアーキテクチャが「ディスク」上のメディアの場所を表すNSURLを本当に必要としているということです。これを使用して、メディアをサーバーにアップロードし、さらに処理します。

これはALAssetで簡単でした:

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

しかし、私はPHAssetでこの機能を見ていません。私は電話できると思います:

    imageManager.requestImageDataForAsset

ファイルシステムの一時的な場所に書き込みますが、潜在的に遅いことは言うまでもなく、非常に重くて無駄です。

これを取得する方法はありますか、iOS7用のNSURLとiOS8用の他の方法のみを使用するようにアプリのリファクタリングを行う予定ですか?

39
Paul Cezanne

[imageManagerrequestAVAssetForVideo...]を使用すると、AVAssetが返されます。そのAVAssetは実際にはAVURLAssetであるため、キャストすると、-urlプロパティにアクセスできます。

これから新しいアセットを作成できるかどうかはわかりませんが、場所はわかります。

24
jlw

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

}
17
Adam Studenic

PHAssetがある場合は、次のように、上記のアセットのURLを取得できます。

[asset requestContentEditingInputWithOptions:editOptions
                           completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
    NSURL *imageURL = contentEditingInput.fullSizeImageURL;
}];
9
Sahil

PHObjectの新しい localIdentifier プロパティを使用します。 (PHAssetはこれを継承します)。

ALAsset URLと同様の機能を提供します。つまり、メソッドを呼び出すことでアセットをロードできます

+[PHAsset fetchAssetsWithLocalIdentifiers:identifiers options:options]
9
bcattle

上記のすべてのソリューションは、スローモーションビデオでは機能しません。私が見つけたソリューションは、すべてのビデオアセットタイプを処理します。

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
        }
    }
}
5
desmond

この回答を参照してください here

そして、これは ここ です。

私の経験では、完全にアクセスできる/信頼できるURLを取得するために、最初にアセットをディスクにエクスポートする必要があります。

上記にリンクされている回答は、これを行う方法を説明しています。

3
Alfie Hanssen

@jlwからのコメントから隠されたgemを投稿したいだけです

@ rishu1992スローモーションビデオの場合、AVCompositionの(mediaType AVMediaTypeVideoの)AVCompositionTrackを取得し、その最初のセグメント(AVCompositionTrackSegmentタイプの)を取得してから、sourceURLプロパティにアクセスします。 -jlw 15年8月25日11:52で

1
Oliver Hu

PHAssetからurlを指定して、Swift 2でutil funcを準備していました(ただし、PHAsset)。この答えでそれを共有すると、誰かを助けるかもしれません。

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

これを確認してください 回答

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
1
Lizhen Hu

私はビデオファイルで同様の問題を抱えていました、私のために働いたのは:

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です。

0
Gamec