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 accumulatedBytes: Int64 = 0
private var currentFileBytes: Int64 = 0 private var currentFileBytes: Int64 = 0
private var lastFraction: Double = 0 private var lastFraction: Double = 0
private var fileIndex: Int = 0
private var lastReportedOverallFraction: Double = 0
init(totalExpectedBytes: Int64?) { init(totalExpectedBytes: Int64?) {
self.totalExpectedBytes = totalExpectedBytes self.totalExpectedBytes = totalExpectedBytes
@@ -398,13 +400,22 @@ final class YTDLPProgressParser: @unchecked Sendable {
) -> (overallFraction: Double, displaySizeStr: String) { ) -> (overallFraction: Double, displaySizeStr: String) {
if fraction < lastFraction && lastFraction > 0.95 { if fraction < lastFraction && lastFraction > 0.95 {
accumulatedBytes += currentFileBytes accumulatedBytes += currentFileBytes
fileIndex += 1
} }
currentFileBytes = parsedSize currentFileBytes = parsedSize
lastFraction = fraction lastFraction = fraction
let totalDownloadedBytes = accumulatedBytes + Int64(Double(parsedSize) * 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 overallFraction = fraction
var displaySizeStr = sizeStr var displaySizeStr = sizeStr
@@ -414,6 +425,10 @@ final class YTDLPProgressParser: @unchecked Sendable {
displaySizeStr = ByteFormatter.string(overallTotalBytes) displaySizeStr = ByteFormatter.string(overallTotalBytes)
} }
// Ensure overallFraction never decreases visually
overallFraction = max(lastReportedOverallFraction, overallFraction)
lastReportedOverallFraction = overallFraction
return (overallFraction, displaySizeStr) return (overallFraction, displaySizeStr)
} }