From 209193e4cfcaa5f1056ab915f08575fca93095e3 Mon Sep 17 00:00:00 2001 From: ScrubN <72096833+ScrubN@users.noreply.github.com> Date: Wed, 10 Jul 2024 21:52:32 -0400 Subject: [PATCH 1/3] Support "best"/"source" and "worst" quality keywords in clip downloader --- TwitchDownloaderCore/ClipDownloader.cs | 49 ++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/TwitchDownloaderCore/ClipDownloader.cs b/TwitchDownloaderCore/ClipDownloader.cs index 12151782..ee5ba252 100644 --- a/TwitchDownloaderCore/ClipDownloader.cs +++ b/TwitchDownloaderCore/ClipDownloader.cs @@ -3,6 +3,7 @@ using System.IO; using System.Linq; using System.Net.Http; +using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Web; @@ -126,24 +127,60 @@ private async Task GetDownloadUrl() throw new NullReferenceException("Clip has no video qualities, deleted possibly?"); } - string downloadUrl = ""; + var downloadUrl = GetDownloadUrlForQuality(clip, downloadOptions.Quality); + + return downloadUrl + "?sig=" + clip.playbackAccessToken.signature + "&token=" + HttpUtility.UrlEncode(clip.playbackAccessToken.value); + } + + private static string GetDownloadUrlForQuality(ClipToken clip, string qualityString) + { + Debug.Assert(clip.videoQualities.OrderBy(x => x, new ClipQualityComparer()).SequenceEqual(clip.videoQualities)); + + if (TryGetKeywordQuality(clip, qualityString, out var downloadUrl)) + { + return downloadUrl; + } foreach (var quality in clip.videoQualities) { - if (quality.quality + "p" + (Math.Round(quality.frameRate) == 30 ? "" : Math.Round(quality.frameRate).ToString("F0")) == downloadOptions.Quality) + if (quality.quality + "p" + (Math.Round(quality.frameRate) == 30 ? "" : Math.Round(quality.frameRate).ToString("F0")) == qualityString) { - downloadUrl = quality.sourceURL; + return quality.sourceURL; } } - if (downloadUrl == "") + return BestQuality(clip).sourceURL; + } + + private static bool TryGetKeywordQuality(ClipToken clip, string qualityString, out string downloadUrl) + { + if (string.IsNullOrWhiteSpace(qualityString)) + { + downloadUrl = BestQuality(clip).sourceURL; + return true; + } + + if (qualityString.Contains("best", StringComparison.OrdinalIgnoreCase) + || qualityString.Contains("source", StringComparison.OrdinalIgnoreCase)) { - downloadUrl = clip.videoQualities.First().sourceURL; + downloadUrl = BestQuality(clip).sourceURL; + return true; } - return downloadUrl + "?sig=" + clip.playbackAccessToken.signature + "&token=" + HttpUtility.UrlEncode(clip.playbackAccessToken.value); + if (qualityString.Contains("worst", StringComparison.OrdinalIgnoreCase)) + { + downloadUrl = WorstQuality(clip).sourceURL; + return true; + } + + downloadUrl = null; + return false; } + private static VideoQuality BestQuality(ClipToken clip) => clip.videoQualities.First(); + + private static VideoQuality WorstQuality(ClipToken clip) => clip.videoQualities.Last(); + private static async Task DownloadFileTaskAsync(string url, FileStream fs, int throttleKib, IProgress progress, CancellationToken cancellationToken) { var request = new HttpRequestMessage(HttpMethod.Get, url); From c6a3e04bc1947f24e6998ca65a805f35528efe8e Mon Sep 17 00:00:00 2001 From: ScrubN <72096833+ScrubN@users.noreply.github.com> Date: Wed, 10 Jul 2024 22:09:40 -0400 Subject: [PATCH 2/3] Make clip quality selection more robust --- TwitchDownloaderCore/ClipDownloader.cs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/TwitchDownloaderCore/ClipDownloader.cs b/TwitchDownloaderCore/ClipDownloader.cs index ee5ba252..34547b27 100644 --- a/TwitchDownloaderCore/ClipDownloader.cs +++ b/TwitchDownloaderCore/ClipDownloader.cs @@ -141,9 +141,25 @@ private static string GetDownloadUrlForQuality(ClipToken clip, string qualityStr return downloadUrl; } - foreach (var quality in clip.videoQualities) + if (qualityString.Contains('p')) { - if (quality.quality + "p" + (Math.Round(quality.frameRate) == 30 ? "" : Math.Round(quality.frameRate).ToString("F0")) == qualityString) + foreach (var quality in clip.videoQualities) + { + var framerate = (int)Math.Round(quality.frameRate); + var framerateString = qualityString.EndsWith('p') && framerate == 30 + ? "" + : framerate.ToString("F0"); + + if ($"{quality.quality}p{framerateString}" == qualityString) + { + return quality.sourceURL; + } + } + } + else + { + var quality = clip.videoQualities.FirstOrDefault(quality => quality.quality == qualityString); + if (quality is not null) { return quality.sourceURL; } From ff388da382995f005daad03d13be9d0e733a4b94 Mon Sep 17 00:00:00 2001 From: ScrubN <72096833+ScrubN@users.noreply.github.com> Date: Wed, 10 Jul 2024 22:10:50 -0400 Subject: [PATCH 3/3] Cleanup imports --- TwitchDownloaderCore/ClipDownloader.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/TwitchDownloaderCore/ClipDownloader.cs b/TwitchDownloaderCore/ClipDownloader.cs index 34547b27..0ed26659 100644 --- a/TwitchDownloaderCore/ClipDownloader.cs +++ b/TwitchDownloaderCore/ClipDownloader.cs @@ -3,7 +3,6 @@ using System.IO; using System.Linq; using System.Net.Http; -using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Web;