In iOS 10, Apple added offline HLS. In the documentation, they mention:
Important: Downloaded HLS assets are stored on disk in a private bundle format. This bundle format may change over time, and developers should not attempt to access or store files within the bundle directly, but should instead use AVFoundation and other iOS APIs to interact with downloaded assets.
It appears the access to information about these files is limited. I'm trying to find the size of the stored file. Here is what I do. After download finishes, I save the relative path
func urlSession(_ session: URLSession, assetDownloadTask: AVAssetDownloadTask, didFinishDownloadingTo location: URL) {
//Save path
video?.downloadPath = location.relativePath
}
later I reconstruct the file path as follows
if let assetPath = workout.downloadPath {
let baseURL = URL(fileURLWithPath: NSHomeDirectory())
let assetURL = baseURL.appendingPathComponent(assetPath)
This works:
try FileManager.default.removeItem(at: assetURL)
This does not and returns an error that the file doesn't exist:
let att = try FileManager.default.attributesOfItem(atPath: assetURL.absoluteString)
I can load in the video asset as follows and play it offline with:
let avAsset = AVURLAsset(url: assetURL)
But this returns me an empty array:
let tracks = avAsset.tracks(withMediaType: AVMediaTypeVideo)
Once again I'm just trying to get the file size of an offline HLS asset. It appears the other answers on SO for getting a file size using FileManager don't work for these nor do the answers for getting the size of a loaded AVAsset. Thanks in advance.
Here is how to calculate offline HLS (.movpkg) File Size:
/// Calculates HLS File Size.
/// - Parameter directoryPath: file directory path.
/// - Returns: Human Redable File Size.
func getHLSFileSize(at directoryPath: String) -> String? {
var result: String? = nil
let properties: [URLResourceKey] = [.isRegularFileKey,
.totalFileAllocatedSizeKey,
/*.fileAllocatedSizeKey*/]
guard let enumerator = FileManager.default.enumerator(at: URL(fileURLWithPath: directoryPath),
includingPropertiesForKeys: properties,
options: .skipsHiddenFiles,
errorHandler: nil) else {
return nil
}
let urls: [URL] = enumerator
.compactMap { $0 as? URL }
.filter { $0.absoluteString.contains(".frag") }
let regularFileResources: [URLResourceValues] = urls
.compactMap { try? $0.resourceValues(forKeys: Set(properties)) }
.filter { $0.isRegularFile == true }
let sizes: [Int64] = regularFileResources
.compactMap { $0.totalFileAllocatedSize! /* ?? $0.fileAllocatedSize */ }
.compactMap { Int64($0) }
let size = sizes.reduce(0, +)
result = ByteCountFormatter.string(fromByteCount: Int64(size), countStyle: .file)
return result
}
if let url = URL(string: localFileLocation),
let size = self.getHLSFileSize(at: url.path) {
result = String(size)
}
The only way is to sum all files sizes inside a folder where your downloaded content is stored.
- (NSUInteger)hlsFileSize:(NSURL *)fileURL {
NSUInteger size = 0;
let enumerator = [NSFileManager.defaultManager enumeratorAtURL:fileURL includingPropertiesForKeys:nil options:0 errorHandler:nil];
for (NSURL *url in enumerator) {
NSError *error = nil;
// Get values
let resourceValues = [url resourceValuesForKeys:@[NSURLIsRegularFileKey, NSURLFileAllocatedSizeKey, NSURLNameKey] error:&error];
// Skip unregular files
let isRegularFile = [resourceValues[NSURLIsRegularFileKey] boolValue];
if (!isRegularFile) {
continue;
}
let fileAllocatedSize = [resourceValues[NSURLFileAllocatedSizeKey] unsignedLongLongValue];
size += fileAllocatedSize;
}
return size;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With