如何在iOS8中确定视频PHAsset的磁盘文件大小

11

我可以使用iOS8中的Photos框架请求视频PHAsset。我想知道磁盘上的文件大小。PHAsset没有属性可以确定这一点。有人有解决方案吗?(不需要使用Photos框架)

3个回答

31

编辑

关于iOS 9.3版本,针对视频类型的PHAsset使用requestImageDataForAsset将导致返回图像为视频的第一帧,因此现在该方法不再适用。改用下列方法,对于普通视频请求选项可以设置为nil,但是对于慢动作视频,需要设置PHVideoRequestOptionsVersionOriginal

PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
options.version = PHVideoRequestOptionsVersionOriginal;

[[PHImageManager defaultManager] requestAVAssetForVideo:asset options:options resultHandler:^(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info) {
    if ([asset isKindOfClass:[AVURLAsset class]]) {
        AVURLAsset* urlAsset = (AVURLAsset*)asset;

        NSNumber *size;

        [urlAsset.URL getResourceValue:&size forKey:NSURLFileSizeKey error:nil];
        NSLog(@"size is %f",[size floatValue]/(1024.0*1024.0)); //size is 43.703005

    }
}];

对于PHAsset,请使用以下内容:

[[PHImageManager defaultManager] requestImageDataForAsset:asset options:nil resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
        float imageSize = imageData.length;
        //convert to Megabytes
        imageSize = imageSize/(1024*1024);
        NSLog(@"%f",imageSize);
 }];

对于ALAsset:

ALAssetRepresentation *rep = [asset defaultRepresentation];
float imageSize = rep.size/(1024.0*1024.0);

我在一个视频资产上进行了测试,PHAsset显示大小为43.703125,ALAsset显示大小为43.703005。

编辑 对于PHAsset,获取文件大小的另一种方法。但是,正如@Alfie Hanssen提到的,它适用于普通视频,在慢动作视频上,以下方法将在块中返回AVComposition资产,因此我添加了其类型的检查。 对于慢动作视频,请使用requestImageDataForAsset方法。

[[PHImageManager defaultManager] requestAVAssetForVideo:asset options:nil resultHandler:^(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info) {
    if ([asset isKindOfClass:[AVURLAsset class]]) {
        AVURLAsset* urlAsset = (AVURLAsset*)asset;
        NSNumber *size;

        [urlAsset.URL getResourceValue:&size forKey:NSURLFileSizeKey error:nil];
        NSLog(@"size is %f",[size floatValue]/(1024.0*1024.0)); //size is 43.703005
        NSData *data = [NSData dataWithContentsOfURL:urlAsset.URL];
        NSLog(@"length %f",[data length]/(1024.0*1024.0)); // data size is 43.703005
    }
}];

1
谢谢!很奇怪没有requestVideoDataForAsset...而requestImageDataForAsset返回视频的大小。 - jlw
1
是的,我刚刚再次确认了这一点,它们确实是视频。但看起来任何慢动作视频都返回为AVComposition(普通视频确实是AVURLAssets)。检查completionBlock中的info字典参数会显示其他元数据:PHAdjustmentDataKey = "<PHAdjustmentData: 0x174244110> identifier=com.apple.video.slomo version=1.1 data=0x174243d50 (200)"。因此,最好进行类检查以确认转换是否安全。 - Alfie Hanssen
1
在iOS 9.3及以上版本中,使用PHAsset的第一种方法似乎无法正常工作。 - Aravind Bhuvanendran
[[PHImageManager defaultManager] requestImageDataForAsset:asset options:nil resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary info) { float imageSize = imageData.length; //convert to Megabytes imageSize = imageSize/(10241024); NSLog(@"%f",imageSize); }]; - Aravind Bhuvanendran
注意:对于AVComposition(慢动作视频),无法通过requestImageData(for:)(iOS 10.3,Swift)检索文件大小。 - Marcel T
显示剩余7条评论

3

带有文件大小格式的Swift版本:

    let options = PHVideoRequestOptions()
    options.version = .original

    PHImageManager.default().requestAVAsset(forVideo: asset, options: options) { avAsset, _, _ in
        if let urlAsset = avAsset as? AVURLAsset {  // Could be AVComposition class
            if let resourceValues = try? urlAsset.url.resourceValues(forKeys: [.fileSizeKey]),
                let fileSize = resourceValues.fileSize {

                let formatter = ByteCountFormatter()
                formatter.countStyle = .file
                let string = formatter.string(fromByteCount: Int64(fileSize))

                print(string)
            }
        }
    }

0
您有很高的几率,想要了解的视频大小不是AVURLAsset类型。但这没关系,在幕后有更多文件组成了您的视频(例如原始样本、慢动作时间范围、过滤器等等...),因为您想知道一个具体可播放文件的大小。我不确定估计的文件大小在这种情况下是否符合实际,但应该按照以下方式完成:
PHImageManager.defaultManager().requestExportSessionForVideo(asset, options: nil, exportPreset: AVAssetExportPresetHighestQuality, resultHandler: { (assetExportSession, info) -> Void in // Here you set values that specifies your video (original, after edit, slow-mo, ...) and that affects resulting size. 
    assetExportSession.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(asset.duration, 30)) // Time interval is default from zero to infinite so it needs to be set prior to file size computations. Time scale is I believe (it is "only" preferred value) not important in this case.
    let HERE_YOU_ARE = assetExportSession.estimatedOutputFileLength
})

1
只是一个提醒,文档中说assetExportSession.estimatedOutputFileLength对于AVAssetExportPresetPassThrough总是返回0。请注意... - Alfie Hanssen
请注意,由于estimatedOutputFileLength是估计输出文件的大小,因此您不能认为它是实际文件大小。在我的情况下,有30 MB的差异。 - Marcel T

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接