From 04cf234974b18a81b95f1041be3fea11644b1909 Mon Sep 17 00:00:00 2001 From: nilaoda Date: Sun, 30 Jun 2024 20:27:54 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A6=96=E6=AC=A1=E5=8A=A0=E8=BD=BDURL?= =?UTF-8?q?=E6=97=B6=E5=A2=9E=E5=8A=A0=E9=87=8D=E8=AF=95=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20(#413)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #355 --- .gitignore | 3 ++ src/N_m3u8DL-RE.Common/Util/RetryUtil.cs | 38 +++++++++++++++++++++++ src/N_m3u8DL-RE.Parser/StreamExtractor.cs | 25 +++++---------- src/N_m3u8DL-RE/Program.cs | 16 +++++----- 4 files changed, 57 insertions(+), 25 deletions(-) create mode 100644 src/N_m3u8DL-RE.Common/Util/RetryUtil.cs diff --git a/.gitignore b/.gitignore index 35a2a08..fdb1c97 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,9 @@ bld/ # Uncomment if you have tasks that create the project's static files in wwwroot #wwwroot/ +# Rider +.idea + # Visual Studio 2017 auto generated files Generated\ Files/ diff --git a/src/N_m3u8DL-RE.Common/Util/RetryUtil.cs b/src/N_m3u8DL-RE.Common/Util/RetryUtil.cs new file mode 100644 index 0000000..096c6e3 --- /dev/null +++ b/src/N_m3u8DL-RE.Common/Util/RetryUtil.cs @@ -0,0 +1,38 @@ +using System.Net; +using N_m3u8DL_RE.Common.Log; +using Spectre.Console; + +namespace N_m3u8DL_RE.Common.Util; + +public class RetryUtil +{ + public static async Task WebRequestRetryAsync(Func> funcAsync, int maxRetries = 10, int retryDelayMilliseconds = 1500, int retryDelayIncrementMilliseconds = 0) + { + var retryCount = 0; + var result = default(T); + Exception currentException = new(); + + while (retryCount < maxRetries) + { + try + { + result = await funcAsync(); + break; + } + catch (Exception ex) when (ex is WebException or IOException or HttpRequestException) + { + currentException = ex; + retryCount++; + Logger.WarnMarkUp($"[grey]{ex.Message.EscapeMarkup()} ({retryCount}/{maxRetries})[/]"); + await Task.Delay(retryDelayMilliseconds + (retryDelayIncrementMilliseconds * (retryCount - 1))); + } + } + + if (retryCount == maxRetries) + { + throw new Exception($"Failed to execute action after {maxRetries} retries.", currentException); + } + + return result; + } +} \ No newline at end of file diff --git a/src/N_m3u8DL-RE.Parser/StreamExtractor.cs b/src/N_m3u8DL-RE.Parser/StreamExtractor.cs index 8d0d92d..81215ca 100644 --- a/src/N_m3u8DL-RE.Parser/StreamExtractor.cs +++ b/src/N_m3u8DL-RE.Parser/StreamExtractor.cs @@ -30,25 +30,25 @@ namespace N_m3u8DL_RE.Parser this.parserConfig = parserConfig; } - public void LoadSourceFromUrl(string url) + public async Task LoadSourceFromUrlAsync(string url) { Logger.Info(ResString.loadingUrl + url); if (url.StartsWith("file:")) { var uri = new Uri(url); - this.rawText = File.ReadAllText(uri.LocalPath); + this.rawText = await File.ReadAllTextAsync(uri.LocalPath); parserConfig.OriginalUrl = parserConfig.Url = url; } else if (url.StartsWith("http")) { parserConfig.OriginalUrl = url; - (this.rawText, url) = HTTPUtil.GetWebSourceAndNewUrlAsync(url, parserConfig.Headers).Result; + (this.rawText, url) = await HTTPUtil.GetWebSourceAndNewUrlAsync(url, parserConfig.Headers); parserConfig.Url = url; } else if (File.Exists(url)) { url = Path.GetFullPath(url); - this.rawText = File.ReadAllText(url); + this.rawText = await File.ReadAllTextAsync(url); parserConfig.OriginalUrl = parserConfig.Url = new Uri(url).AbsoluteUri; } this.rawText = rawText.Trim(); @@ -134,22 +134,11 @@ namespace N_m3u8DL_RE.Parser try { await semaphore.WaitAsync(); - int retryCount = 5; //增加重试 - reGet: - try + await RetryUtil.WebRequestRetryAsync(async () => { await extractor.RefreshPlayListAsync(streamSpecs); - } - catch (Exception ex) - { - if (retryCount-- > 0) - { - Logger.WarnMarkUp($"[grey]Refresh Exception: {ex.Message.EscapeMarkup()} retryCount: {retryCount}[/]"); - await Task.Delay(1000); - goto reGet; - } - else throw; - } + return true; + }, retryDelayMilliseconds: 1000, maxRetries: 5); } finally { diff --git a/src/N_m3u8DL-RE/Program.cs b/src/N_m3u8DL-RE/Program.cs index b0dac1e..2f0c0b5 100644 --- a/src/N_m3u8DL-RE/Program.cs +++ b/src/N_m3u8DL-RE/Program.cs @@ -62,11 +62,9 @@ namespace N_m3u8DL_RE static int GetOrder(StreamSpec streamSpec) { if (streamSpec.Channels == null) return 0; - else - { - var str = streamSpec.Channels.Split('/')[0]; - return int.TryParse(str, out var order) ? order : 0; - } + + var str = streamSpec.Channels.Split('/')[0]; + return int.TryParse(str, out var order) ? order : 0; } static async Task DoWorkAsync(MyOption option) @@ -208,8 +206,12 @@ namespace N_m3u8DL_RE //流提取器配置 var extractor = new StreamExtractor(parserConfig); - extractor.LoadSourceFromUrl(url); - + // 从链接加载内容 + await RetryUtil.WebRequestRetryAsync(async () => + { + await extractor.LoadSourceFromUrlAsync(url); + return true; + }); //解析流信息 var streams = await extractor.ExtractStreamsAsync();