iOS 离线 HLS 文件大小

Posted

技术标签:

【中文标题】iOS 离线 HLS 文件大小【英文标题】:iOS offline HLS file size 【发布时间】:2017-03-03 20:19:06 【问题描述】:

ios 10 中,Apple 添加了离线 HLS。在文档中,他们提到:

重要提示:下载的 HLS 资产存储在磁盘上的私有 捆绑格式。此捆绑包格式可能会随着时间而改变,开发人员 不应尝试访问或存储包中的文件 直接,但应改为使用 AVFoundation 和其他 iOS API 与下载的资产交互。

似乎对有关这些文件的信息的访问受到限制。我正在尝试查找存储文件的大小。这就是我所做的。下载完成后,我保存相对路径

func urlSession(_ session: URLSession, assetDownloadTask: AVAssetDownloadTask, didFinishDownloadingTo location: URL) 
        //Save path
        video?.downloadPath = location.relativePath

    

稍后我重构文件路径如下

if let assetPath = workout.downloadPath 
                let baseURL = URL(fileURLWithPath: NSHomeDirectory())
                let assetURL = baseURL.appendingPathComponent(assetPath)

这行得通:

try FileManager.default.removeItem(at: assetURL)

这不会并返回文件不存在的错误:

let att = try FileManager.default.attributesOfItem(atPath: assetURL.absoluteString)

我可以按如下方式加载视频资产并离线播放:

let avAsset = AVURLAsset(url: assetURL)

但这会返回一个空数组:

let tracks = avAsset.tracks(withMediaType: AVMediaTypeVideo)

我再次尝试获取离线 HLS 资产的文件大小。看来 SO 上使用 FileManager 获取文件大小的其他答案不适用于这些,也不适用于获取加载的 AVAsset 的大小。提前致谢。

【问题讨论】:

【参考方案1】:

唯一的方法是将存储下载内容的文件夹中的所有文件大小相加。

- (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;

【讨论】:

【参考方案2】:

Swift 5.3 解决方案

这里是如何计算离线 HLS (.movpkg) 文件大小:

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

【讨论】:

干净整洁?【参考方案3】:

试试这个:

let att = try FileManager.default.attributesOfItem(atPath: assetURL.path)

【讨论】:

嘿,所以我现在实际上得到了属性,但是文件大小似乎完全错误。我下载了两个文件,它们都为“let fileSize = attr[FileAttributeKey.size] as!UInt64”返回 204 首先它们都不应该那么小,而且它们的大小都非常不同。 这里有同样的问题。 我曾经遇到过同样的问题,这就是为什么我(通常)使用这个 gist 中的函数来获得正确的文件大小估计:gist.github.com/blender/a75f589e6bd86aa2121618155cbdf827 当使用 allocatedSizeOfDirectory(at:) 和你的assetURL 时,它应该可以工作.我得到了 1435750400 字节,这正是手机对该资产的存储估计值 (1.44Gb)

以上是关于iOS 离线 HLS 文件大小的主要内容,如果未能解决你的问题,请参考以下文章

iOS获取缓存文件的大小并清除缓存

iOS 可以不使用 AVAssetDownloadURLSession 离线下载 HLS 吗?

如何限制在 Safari(MacOS 和 iOS)中暂停时获取 hls 段文件

iOS缓存功能

AVPlayerLayer 不在 iOS 11 中渲染离线 HLS 视频

下载和播放离线 HLS 内容 - iOS 10