使用AVAssetDownloadURLSession纠正脱机下载的进度

时间:2019-03-14 10:30:04

标签: ios download avfoundation offline progress

感谢AVAssetDownloadURLSession,iOS 11的AVAssetDownloadDelegate使用makeAssetDownloadTask(...)和aggregateAssetDownloadTask(...)方法,我正在下载离线视频。

一切正常,但我只想让用户尽可能准确地了解每次下载的进度。

为此,我使用:

- urlSession(_ session: URLSession, assetDownloadTask: AVAssetDownloadTask, didLoad timeRange: CMTimeRange, totalTimeRangesLoaded loadedTimeRanges: [NSValue], timeRangeExpectedToLoad: CMTimeRange)

- urlSession(_ session: URLSession, aggregateAssetDownloadTask: AVAggregateAssetDownloadTask, didLoad timeRange: CMTimeRange, totalTimeRangesLoaded loadedTimeRanges: [NSValue], timeRangeExpectedToLoad: CMTimeRange, for mediaSelection: AVMediaSelection)

使用这些方法,我可以分别计算视频和每个音轨(音频/字幕)的下载进度。因此,我假设视频占下载量的70%,对于曲目,它是30%除以曲目数量。 我将每个项目的下载进度存储在一个临时词典中(乘以它们的比率),并为下载添加每个进度以具有全局表示。

最后,它工作正常,但不如预期的那样平滑。例如,我花了3分钟来下载内容,但是如果音轨的重量很轻,进度将在1秒内从70%跃升到85%(如果我有2条音轨可供下载),然后立即变慢。 我想取得全球进步。

我对此解决方案绝对不满意,但是我目前找不到其他解决方案。

你们中的一些人有什么想法/解决方案吗?

谢谢大家

1 个答案:

答案 0 :(得分:0)

解决方案

首先,这只是我的情况,您应该根据需要更新方法。

在我的情况下,作为最复杂的数组示例,我有这样的东西:

[English(soun),Turkish(soun),English(sbtl),Turkish(sbtl)]

我们将为所有音频提供 80%的音频,为所有字幕提供 20%

总计算公式必须是这样的:

(100*(0,80/2))+(100*(0,80/2))+(100*(0,20/2))+(100(0,20/2))

我们需要一个枚举来表示AVMediaType

// AVMediaType
enum MediaType: String {
    // Sound
    case soun
        
    // Subtitle
    case sbtl
      
    // Closed Caption
    // case clcp // Removed for simplifying the example.
}

此外,我们将需要一个词典来处理资产下载进度:

var totalDownloadProgressForAsset = [String: Double]()

这是方法:

public func getTotalProgress() -> Double {
    var result = 0.0
    let soundMultiplier          = 0.80
    let subtitleMultiplier       = 0.20
    var soundCount = 0
    var subtitleCount  = 0
    
    for (key, _) in totalDownloadProgressForAsset {
        let mediaTypeKey = String(key.suffix(4))
        let type = MediaType(rawValue: mediaTypeKey)
        
        switch type {
        case .soun:
            soundCount += 1
        case .sbtl:
            subtitleCount += 1
        case .none:
            break
        }
    }
                    
    for (key, value) in totalDownloadProgressForAsset {
        let mediaTypeKey = String(key.suffix(4))
        let type = MediaType(rawValue: mediaTypeKey)
        
        switch type {
        case .soun:
            result += Double(value*(soundMultiplier/Double(soundCount)))
        case .sbtl:
            result += Double(value*(subtitleMultiplier/Double(subtitleCount)))
        case .none:
            break
        }
    }
    
    return result
}

当然,我们可以用不同的方式写这个,这只是举例。

随时询问任何问题。