From ffd4b5970d9796526dd17f505f9adbb3fec4d829 Mon Sep 17 00:00:00 2001
From: Dragan Simic <dragan.simic@gmail.com>
Date: Thu, 8 Jul 2021 21:46:00 +0200
Subject: [PATCH] Improve non-final progress updates and displayed values

---
 youtube_dl/downloader/common.py | 30 ++++++++++++++++--------------
 youtube_dl/utils.py             |  6 ++++--
 2 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/youtube_dl/downloader/common.py b/youtube_dl/downloader/common.py
index 1cdba89cd..4a52a1e4a 100644
--- a/youtube_dl/downloader/common.py
+++ b/youtube_dl/downloader/common.py
@@ -57,6 +57,7 @@ class FileDownloader(object):
 
     _TEST_FILE_SIZE = 10241
     params = None
+    progress_update = time.time()
 
     def __init__(self, ydl, params):
         """Create a FileDownloader object with the given options."""
@@ -116,8 +117,8 @@ class FileDownloader(object):
     @staticmethod
     def format_speed(speed):
         if speed is None:
-            return '%10s' % '---b/s'
-        return '%10s' % ('%s/s' % format_bytes(speed))
+            return '%12s' % '--- B/s'
+        return '%12s' % ('%s/s' % format_bytes(speed))
 
     @staticmethod
     def format_retries(retries):
@@ -266,32 +267,33 @@ class FileDownloader(object):
         if s['status'] != 'downloading':
             return
 
+        # Show non-final progress updates no more often than once per second
+        tstamp = time.time()
+        if tstamp - self.progress_update < 1:
+            return
+        self.progress_update = tstamp
+
         if s.get('eta') is not None:
             s['_eta_str'] = self.format_eta(s['eta'])
         else:
-            s['_eta_str'] = 'Unknown ETA'
+            s['_eta_str'] = 'unknown'
 
         if s.get('total_bytes') and s.get('downloaded_bytes') is not None:
             s['_percent_str'] = self.format_percent(100 * s['downloaded_bytes'] / s['total_bytes'])
         elif s.get('total_bytes_estimate') and s.get('downloaded_bytes') is not None:
             s['_percent_str'] = self.format_percent(100 * s['downloaded_bytes'] / s['total_bytes_estimate'])
         else:
-            if s.get('downloaded_bytes') == 0:
-                s['_percent_str'] = self.format_percent(0)
-            else:
-                s['_percent_str'] = 'Unknown %'
+            s['_percent_str'] = self.format_percent(0 if s.get('downloaded_bytes') == 0 else None)
 
-        if s.get('speed') is not None:
-            s['_speed_str'] = self.format_speed(s['speed'])
-        else:
-            s['_speed_str'] = 'Unknown speed'
+        # Missing 'speed' is already handled properly in self.format_speed()
+        s['_speed_str'] = self.format_speed(s.get('speed'))
 
         if s.get('total_bytes') is not None:
             s['_total_bytes_str'] = format_bytes(s['total_bytes'])
-            msg_template = '%(_percent_str)s of %(_total_bytes_str)s at %(_speed_str)s ETA %(_eta_str)s'
+            msg_template = '%(_percent_str)s of %(_total_bytes_str)s at %(_speed_str)s, ETA %(_eta_str)s'
         elif s.get('total_bytes_estimate') is not None:
             s['_total_bytes_estimate_str'] = format_bytes(s['total_bytes_estimate'])
-            msg_template = '%(_percent_str)s of ~%(_total_bytes_estimate_str)s at %(_speed_str)s ETA %(_eta_str)s'
+            msg_template = '%(_percent_str)s of ~%(_total_bytes_estimate_str)s at %(_speed_str)s, ETA %(_eta_str)s'
         else:
             if s.get('downloaded_bytes') is not None:
                 s['_downloaded_bytes_str'] = format_bytes(s['downloaded_bytes'])
@@ -301,7 +303,7 @@ class FileDownloader(object):
                 else:
                     msg_template = '%(_downloaded_bytes_str)s at %(_speed_str)s'
             else:
-                msg_template = '%(_percent_str)s % at %(_speed_str)s ETA %(_eta_str)s'
+                msg_template = '%(_percent_str)s % at %(_speed_str)s, ETA %(_eta_str)s'
 
         self._report_progress_status(msg_template % s)
 
diff --git a/youtube_dl/utils.py b/youtube_dl/utils.py
index e722eed58..732dc727b 100644
--- a/youtube_dl/utils.py
+++ b/youtube_dl/utils.py
@@ -3396,10 +3396,12 @@ def format_bytes(bytes):
     if bytes == 0.0:
         exponent = 0
     else:
-        exponent = int(math.log(bytes, 1024.0))
+        # Display user-friendly values, e.g. "1001.45 KiB" is much less
+        # user-friendly than "1.00 MiB"
+        exponent = int(math.log(bytes, 1000.0))
     suffix = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'][exponent]
     converted = float(bytes) / float(1024 ** exponent)
-    return '%.2f%s' % (converted, suffix)
+    return '%.2f %s' % (converted, suffix)
 
 
 def lookup_unit_table(unit_table, s):