简体   繁体   English

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

[英]How can I determine file size on disk of a video PHAsset in iOS8

I can request a video PHAsset using the Photos framework in iOS8.我可以使用 iOS8 中的照片框架请求视频 PHAsset。 I'd like to know how big the file is on disk.我想知道磁盘上的文件有多大。 There doesn't seem to be a property of PHAsset to determine that.似乎没有 PHAsset 的属性来确定这一点。 Does anyone have a solution?有没有人有办法解决吗? (Using Photos framework not required) (不需要使用照片框架)

Edit编辑

As for iOS 9.3, using requestImageDataForAsset on a video type PHAsset will result in an image, which is the first frame of the video, so it doesn't work anymore.对于 iOS 9.3,在视频类型PHAsset上使用requestImageDataForAsset将产生图像,这是视频的第一帧,因此不再起作用。 Use the following method instead, for normal video, request option can be nil , but for slow motion video, PHVideoRequestOptionsVersionOriginal needs to be set.改用下面的方法,对于普通视频,请求选项可以为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

    }
}];

//original answer //原始答案

For PHAsset, use this:对于 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);
 }];

For ALAsset:对于 ALAsset:

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

I tested on one video asset, PHAsset shows the size as 43.703125, ALAsset shows the size as 43.703005.我测试了一个视频资产,PHAsset 显示大小为 43.703125,ALAsset 显示大小为 43.703005。

Edit For PHAsset, another way to get file size. Edit For PHAsset,另一种获取文件大小的方法。 But as @Alfie Hanssen mentioned, it works on normal video, for slow motion video, the following method will return a AVComposition asset in the block, so I added the check for its type.但正如@Alfie Hanssen 提到的,它适用于普通视频,对于慢动作视频,以下方法将返回块中的 AVComposition 资产,因此我添加了对其类型的检查。 For slow motion video, use the requestImageDataForAsset method.对于慢动作视频,请使用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
    }
}];

Swift version with file size formatting:带有文件大小格式的 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)
            }
        }
    }

You heave pretty high chance, that video you want to know is's size is not type of AVURLAsset .你有很大的机会,你想知道的视频的大小不是AVURLAsset类型。 But it's ok that under the hood there are more files that your video is composited of (for example raw samples, slow-mo time ranges, filters, etc...), because you want to know size of a concrete playable file.但没关系,在幕后有更多的文件可以合成您的视频(例如原始样本、慢动作时间范围、过滤器等),因为您想知道具体的可播放文件的大小。 I'm not sure how estimated file size meets reality in this case, but this is how it should be done:在这种情况下,我不确定估计的文件大小如何满足现实,但应该这样做:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM