From 79f4c8f0e9c8f25de26f3d8c2736e698371b8a1f Mon Sep 17 00:00:00 2001 From: NimBold Date: Thu, 11 Jun 2026 14:38:29 +0330 Subject: [PATCH] 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. --- Sources/Firelink/MediaDownloadEngine.swift | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Sources/Firelink/MediaDownloadEngine.swift b/Sources/Firelink/MediaDownloadEngine.swift index 949e7f5..d7248a8 100644 --- a/Sources/Firelink/MediaDownloadEngine.swift +++ b/Sources/Firelink/MediaDownloadEngine.swift @@ -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) }