I can request a video PHAsset using the Photos framework in iOS8. 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. 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. Use the following method instead, for normal video, request option can be nil
, but for slow motion video, PHVideoRequestOptionsVersionOriginal
needs to be set.
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:
[[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:
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.
Edit
For PHAsset, another way to get file size. 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. For slow motion video, use the requestImageDataForAsset
method.
[[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
}
}];
PHAdjustmentDataKey = "<PHAdjustmentData: 0x174244110> identifier=com.apple.video.slomo version=1.1 data=0x174243d50 (200)";
. So it looks like it's a good idea to do a class check to confirm that a cast is safe. –
Disquietude requestImageData(for:)
(iOS 10.3, Swift) –
Jocund Swift version with file size formatting:
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
. 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
})
assetExportSession.estimatedOutputFileLength
will always return 0 for AVAssetExportPresetPassThrough
. Beware... –
Disquietude estimatedOutputFileLength
you can not consider that it is the actual filesize. In my case there was a difference of 30 MB. –
Jocund © 2022 - 2024 — McMap. All rights reserved.