diff --git a/TwitchDownloaderCLI/Tools/FfmpegHandler.cs b/TwitchDownloaderCLI/Tools/FfmpegHandler.cs index 8684d8e6..7a4bd379 100644 --- a/TwitchDownloaderCLI/Tools/FfmpegHandler.cs +++ b/TwitchDownloaderCLI/Tools/FfmpegHandler.cs @@ -1,7 +1,10 @@ using Mono.Unix; using System; +using System.Collections.Concurrent; using System.IO; +using System.Linq; using System.Runtime.InteropServices; +using System.Threading; using TwitchDownloaderCLI.Modes.Arguments; using Xabe.FFmpeg; using Xabe.FFmpeg.Downloader; @@ -24,8 +27,7 @@ private static void DownloadFfmpeg() { Console.Write("[INFO] - Downloading FFmpeg"); - var progressHandler = new Progress(); - progressHandler.ProgressChanged += new XabeProgressHandler().OnProgressReceived; + using var progressHandler = new XabeProgressHandler(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { @@ -63,20 +65,41 @@ public static void DetectFfmpeg(string ffmpegPath) Environment.Exit(1); } - private class XabeProgressHandler + private sealed class XabeProgressHandler : IProgress, IDisposable { private int _lastPercent = -1; + private readonly ConcurrentQueue _percentQueue = new(); + private readonly Timer _timer; - internal void OnProgressReceived(object sender, ProgressInfo e) + public XabeProgressHandler() { - var percent = (int)(e.DownloadedBytes / (double)e.TotalBytes * 100); + _timer = new Timer(Callback, _percentQueue, 0, 100); + + static void Callback(object state) + { + if (state is not ConcurrentQueue { IsEmpty: false } queue) return; + + var currentPercent = queue.Max(); + Console.Write($"\r[INFO] - Downloading FFmpeg {currentPercent}%"); + } + } + + public void Report(ProgressInfo value) + { + var percent = (int)(value.DownloadedBytes / (double)value.TotalBytes * 100); if (percent > _lastPercent) { _lastPercent = percent; - Console.Write($"\r[INFO] - Downloading FFmpeg {percent}%"); + _percentQueue.Enqueue(percent); } } + + public void Dispose() + { + _timer?.Dispose(); + _percentQueue.Clear(); + } } } } \ No newline at end of file diff --git a/TwitchDownloaderWPF/MainWindow.xaml.cs b/TwitchDownloaderWPF/MainWindow.xaml.cs index aaf42a58..46ff2267 100644 --- a/TwitchDownloaderWPF/MainWindow.xaml.cs +++ b/TwitchDownloaderWPF/MainWindow.xaml.cs @@ -5,6 +5,7 @@ using System.Net; using System.Windows; using TwitchDownloaderWPF.Properties; +using Xabe.FFmpeg; using Xabe.FFmpeg.Downloader; namespace TwitchDownloaderWPF @@ -69,11 +70,16 @@ private async void Window_Loaded(object sender, RoutedEventArgs e) Settings.Default.Save(); } + var currentVersion = Version.Parse("1.53.2"); + Title = $"Twitch Downloader v{currentVersion}"; + + // TODO: extract FFmpeg handling to a dedicated service if (!File.Exists("ffmpeg.exe")) { + var oldTitle = Title; try { - await FFmpegDownloader.GetLatestVersion(FFmpegVersion.Full); + await FFmpegDownloader.GetLatestVersion(FFmpegVersion.Full, new FfmpegDownloadProgress()); } catch (Exception ex) { @@ -88,10 +94,10 @@ private async void Window_Loaded(object sender, RoutedEventArgs e) MessageBox.Show(ex.ToString(), Translations.Strings.VerboseErrorOutput, MessageBoxButton.OK, MessageBoxImage.Error); } } + + Title = oldTitle; } - Version currentVersion = new Version("1.53.2"); - Title = $"Twitch Downloader v{currentVersion}"; AutoUpdater.InstalledVersion = currentVersion; #if !DEBUG if (AppContext.BaseDirectory.StartsWith(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile))) @@ -102,5 +108,32 @@ private async void Window_Loaded(object sender, RoutedEventArgs e) AutoUpdater.Start("https://downloader-update.twitcharchives.workers.dev"); #endif } + + private class FfmpegDownloadProgress : IProgress + { + private int _lastPercent = -1; + + public void Report(ProgressInfo value) + { + var percent = (int)(value.DownloadedBytes / (double)value.TotalBytes * 100); + + if (percent > _lastPercent) + { + var window = Application.Current.MainWindow; + if (window is null) return; + + _lastPercent = percent; + + var oldTitle = window.Title; + if (oldTitle.IndexOf('-') == -1) oldTitle += " -"; + + window.Title = string.Concat( + oldTitle.AsSpan(0, oldTitle.IndexOf('-')), + "- ", + string.Format(Translations.Strings.StatusDownloaderFFmpeg, percent.ToString()) + ); + } + } + } } } diff --git a/TwitchDownloaderWPF/Translations/Strings.Designer.cs b/TwitchDownloaderWPF/Translations/Strings.Designer.cs index 8a438986..0ddc9a35 100644 --- a/TwitchDownloaderWPF/Translations/Strings.Designer.cs +++ b/TwitchDownloaderWPF/Translations/Strings.Designer.cs @@ -1382,6 +1382,15 @@ public static string StatusDone { } } + /// + /// Looks up a localized string similar to Downloading FFmpeg {0}%. + /// + public static string StatusDownloaderFFmpeg { + get { + return ResourceManager.GetString("StatusDownloaderFFmpeg", resourceCulture); + } + } + /// /// Looks up a localized string similar to Downloading. /// diff --git a/TwitchDownloaderWPF/Translations/Strings.es.resx b/TwitchDownloaderWPF/Translations/Strings.es.resx index 35030a92..4228ce6b 100644 --- a/TwitchDownloaderWPF/Translations/Strings.es.resx +++ b/TwitchDownloaderWPF/Translations/Strings.es.resx @@ -775,4 +775,7 @@ Videos per page: + + Downloading FFmpeg {0}% + diff --git a/TwitchDownloaderWPF/Translations/Strings.fr.resx b/TwitchDownloaderWPF/Translations/Strings.fr.resx index f3de78f0..f7a00758 100644 --- a/TwitchDownloaderWPF/Translations/Strings.fr.resx +++ b/TwitchDownloaderWPF/Translations/Strings.fr.resx @@ -774,4 +774,7 @@ Vidéos par page: + + Downloading FFmpeg {0}% + \ No newline at end of file diff --git a/TwitchDownloaderWPF/Translations/Strings.pl.resx b/TwitchDownloaderWPF/Translations/Strings.pl.resx index d7f6e125..f9cb43b9 100644 --- a/TwitchDownloaderWPF/Translations/Strings.pl.resx +++ b/TwitchDownloaderWPF/Translations/Strings.pl.resx @@ -774,4 +774,7 @@ Videos per page: + + Downloading FFmpeg {0}% + \ No newline at end of file diff --git a/TwitchDownloaderWPF/Translations/Strings.resx b/TwitchDownloaderWPF/Translations/Strings.resx index 4ed524b0..0bc72b6b 100644 --- a/TwitchDownloaderWPF/Translations/Strings.resx +++ b/TwitchDownloaderWPF/Translations/Strings.resx @@ -773,4 +773,7 @@ Videos per page: + + Downloading FFmpeg {0}% + \ No newline at end of file diff --git a/TwitchDownloaderWPF/Translations/Strings.ru.resx b/TwitchDownloaderWPF/Translations/Strings.ru.resx index 7e77b56a..454118e6 100644 --- a/TwitchDownloaderWPF/Translations/Strings.ru.resx +++ b/TwitchDownloaderWPF/Translations/Strings.ru.resx @@ -774,4 +774,7 @@ Videos per page: + + Downloading FFmpeg {0}% + \ No newline at end of file diff --git a/TwitchDownloaderWPF/Translations/Strings.tr.resx b/TwitchDownloaderWPF/Translations/Strings.tr.resx index 08b595aa..c830884c 100644 --- a/TwitchDownloaderWPF/Translations/Strings.tr.resx +++ b/TwitchDownloaderWPF/Translations/Strings.tr.resx @@ -775,4 +775,7 @@ Videos per page: + + Downloading FFmpeg {0}% + \ No newline at end of file diff --git a/TwitchDownloaderWPF/Translations/Strings.zh.resx b/TwitchDownloaderWPF/Translations/Strings.zh.resx index a6c708f5..1073660f 100644 --- a/TwitchDownloaderWPF/Translations/Strings.zh.resx +++ b/TwitchDownloaderWPF/Translations/Strings.zh.resx @@ -773,4 +773,7 @@ Videos per page: + + Downloading FFmpeg {0}% + \ No newline at end of file