From 604e52f7f66cfc08502b5cc35f4784310cdc8900 Mon Sep 17 00:00:00 2001
From: nilaoda <nilaoda@live.com>
Date: Mon, 29 May 2023 23:47:06 +0800
Subject: [PATCH] =?UTF-8?q?=E8=AE=A1=E7=AE=97=E4=B8=8B=E8=BD=BD=E9=80=9F?=
 =?UTF-8?q?=E5=BA=A6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 BBDown/BBDownUtil.cs  |  4 ++--
 BBDown/ProgressBar.cs | 48 +++++++++++++++++++++++++++++++++++--------
 2 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/BBDown/BBDownUtil.cs b/BBDown/BBDownUtil.cs
index 4c041164c..2b002e37f 100644
--- a/BBDown/BBDownUtil.cs
+++ b/BBDown/BBDownUtil.cs
@@ -358,7 +358,7 @@ public static async Task DownloadFile(string url, string path, bool aria2c, stri
             try
             {
                 using var progress = new ProgressBar();
-                await RangeDownloadToTmpAsync(0, url, tmpName, 0, null, (_, downloaded, total) => progress.Report((double)downloaded / total));
+                await RangeDownloadToTmpAsync(0, url, tmpName, 0, null, (_, downloaded, total) => progress.Report((double)downloaded / total, downloaded));
                 File.Move(tmpName, path, true);
             }
             catch (Exception)
@@ -406,7 +406,7 @@ await Parallel.ForEachAsync(allClips, async (clip, _) =>
                     await RangeDownloadToTmpAsync(clip.index, url, tmp, clip.from, clip.to == -1 ? null : clip.to, (index, downloaded, _) =>
                     {
                         clipProgress[index] = downloaded;
-                        progress.Report((double)clipProgress.Values.Sum() / fileSize);
+                        progress.Report((double)clipProgress.Values.Sum() / fileSize, clipProgress.Values.Sum());
                     }, true);
                 }
                 catch (NotSupportedException)
diff --git a/BBDown/ProgressBar.cs b/BBDown/ProgressBar.cs
index 7079cffad..e32235e1b 100644
--- a/BBDown/ProgressBar.cs
+++ b/BBDown/ProgressBar.cs
@@ -20,14 +20,21 @@ class ProgressBar : IDisposable, IProgress<double>
 		private bool disposed = false;
 		private int animationIndex = 0;
 
-		public ProgressBar()
+		//速度计算
+		private long lastDownloadedBytes = 0;
+		private long downloadedBytes = 0;
+		private string speedString = "";
+        private readonly Timer speedTimer;
+
+        public ProgressBar()
 		{
 			timer = new Timer(TimerHandler);
+			speedTimer = new Timer(SpeedTimerHandler, null, 100, 1000);
 
-			// A progress bar is only for temporary display in a console window.
-			// If the console output is redirected to a file, draw nothing.
-			// Otherwise, we'll end up with a lot of garbage in the target file.
-			if (!Console.IsOutputRedirected)
+            // A progress bar is only for temporary display in a console window.
+            // If the console output is redirected to a file, draw nothing.
+            // Otherwise, we'll end up with a lot of garbage in the target file.
+            if (!Console.IsOutputRedirected)
 			{
 				ResetTimer();
 			}
@@ -38,20 +45,43 @@ public void Report(double value)
 			// Make sure value is in [0..1] range
 			value = Math.Max(0, Math.Min(1, value));
             Interlocked.Exchange(ref currentProgress, value);
+        }
+
+        public void Report(double value, long bytesCount)
+        {
+            // Make sure value is in [0..1] range
+            value = Math.Max(0, Math.Min(1, value));
+            Interlocked.Exchange(ref currentProgress, value);
+			Interlocked.Exchange(ref downloadedBytes, bytesCount);
+        }
+
+		private void SpeedTimerHandler(object? state)
+		{
+			lock (speedTimer)
+            {
+                if (disposed) return;
+
+                if (downloadedBytes > 0)
+                {
+                    speedString = " - " + BBDownUtil.FormatFileSize(downloadedBytes - lastDownloadedBytes) + "/s";
+                    lastDownloadedBytes = downloadedBytes;
+                }
+            }
 		}
 
-		private void TimerHandler(object? state)
+        private void TimerHandler(object? state)
 		{
 			lock (timer)
 			{
 				if (disposed) return;
 
-				int progressBlockCount = (int)(currentProgress * blockCount);
+                int progressBlockCount = (int)(currentProgress * blockCount);
 				int percent = (int)(currentProgress * 100);
-				string text = string.Format("                            [{0}{1}] {2,3}% {3}",
+				string text = string.Format("                            [{0}{1}] {2,3}% {3}{4}",
 					new string('#', progressBlockCount), new string('-', blockCount - progressBlockCount),
 					percent,
-					animation[animationIndex++ % animation.Length]);
+					animation[animationIndex++ % animation.Length],
+                    speedString);
 				UpdateText(text);
 
 				ResetTimer();