fix: pad overall progress total for first track to prevent 100% snapback

- When yt-dlp underestimates the total bytes (which often excludes audio), the first track download would prematurely hit 100% and then snap back to a lower percentage when the second track started.
- Added a 20% padding to the overall expected size during the first file download to leave room for potential secondary tracks.
- Also added a safeguard to ensure the visually reported overall progress fraction never decreases during a download.
This commit is contained in:
NimBold
2026-06-11 14:38:29 +03:30
parent 2ab3325f30
commit 79f4c8f0e9
+16 -1
View File
@@ -386,6 +386,8 @@ final class YTDLPProgressParser: @unchecked Sendable {
private var accumulatedBytes: Int64 = 0
private var currentFileBytes: Int64 = 0
private var lastFraction: Double = 0
private var fileIndex: Int = 0
private var lastReportedOverallFraction: Double = 0
init(totalExpectedBytes: Int64?) {
self.totalExpectedBytes = totalExpectedBytes
@@ -398,13 +400,22 @@ final class YTDLPProgressParser: @unchecked Sendable {
) -> (overallFraction: Double, displaySizeStr: String) {
if fraction < lastFraction && lastFraction > 0.95 {
accumulatedBytes += currentFileBytes
fileIndex += 1
}
currentFileBytes = parsedSize
lastFraction = fraction
let totalDownloadedBytes = accumulatedBytes + Int64(Double(parsedSize) * fraction)
let overallTotalBytes = max(totalExpectedBytes ?? 0, accumulatedBytes + parsedSize)
var overallTotalBytes = max(totalExpectedBytes ?? 0, accumulatedBytes + parsedSize)
// If we are on the first file, and its size is taking up almost all of totalExpectedBytes,
// we pad overallTotalBytes by 20% to leave room for a potential audio track.
// This prevents the progress bar from prematurely hitting 100%.
if fileIndex == 0 {
let paddedSize = Int64(Double(parsedSize) * 1.2)
overallTotalBytes = max(overallTotalBytes, paddedSize)
}
var overallFraction = fraction
var displaySizeStr = sizeStr
@@ -414,6 +425,10 @@ final class YTDLPProgressParser: @unchecked Sendable {
displaySizeStr = ByteFormatter.string(overallTotalBytes)
}
// Ensure overallFraction never decreases visually
overallFraction = max(lastReportedOverallFraction, overallFraction)
lastReportedOverallFraction = overallFraction
return (overallFraction, displaySizeStr)
}