parent
606db68dbb
commit
04cf234974
|
@ -40,6 +40,9 @@ bld/
|
||||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||||
#wwwroot/
|
#wwwroot/
|
||||||
|
|
||||||
|
# Rider
|
||||||
|
.idea
|
||||||
|
|
||||||
# Visual Studio 2017 auto generated files
|
# Visual Studio 2017 auto generated files
|
||||||
Generated\ Files/
|
Generated\ Files/
|
||||||
|
|
||||||
|
|
|
@ -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<T?> WebRequestRetryAsync<T>(Func<Task<T>> 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,25 +30,25 @@ namespace N_m3u8DL_RE.Parser
|
||||||
this.parserConfig = parserConfig;
|
this.parserConfig = parserConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadSourceFromUrl(string url)
|
public async Task LoadSourceFromUrlAsync(string url)
|
||||||
{
|
{
|
||||||
Logger.Info(ResString.loadingUrl + url);
|
Logger.Info(ResString.loadingUrl + url);
|
||||||
if (url.StartsWith("file:"))
|
if (url.StartsWith("file:"))
|
||||||
{
|
{
|
||||||
var uri = new Uri(url);
|
var uri = new Uri(url);
|
||||||
this.rawText = File.ReadAllText(uri.LocalPath);
|
this.rawText = await File.ReadAllTextAsync(uri.LocalPath);
|
||||||
parserConfig.OriginalUrl = parserConfig.Url = url;
|
parserConfig.OriginalUrl = parserConfig.Url = url;
|
||||||
}
|
}
|
||||||
else if (url.StartsWith("http"))
|
else if (url.StartsWith("http"))
|
||||||
{
|
{
|
||||||
parserConfig.OriginalUrl = url;
|
parserConfig.OriginalUrl = url;
|
||||||
(this.rawText, url) = HTTPUtil.GetWebSourceAndNewUrlAsync(url, parserConfig.Headers).Result;
|
(this.rawText, url) = await HTTPUtil.GetWebSourceAndNewUrlAsync(url, parserConfig.Headers);
|
||||||
parserConfig.Url = url;
|
parserConfig.Url = url;
|
||||||
}
|
}
|
||||||
else if (File.Exists(url))
|
else if (File.Exists(url))
|
||||||
{
|
{
|
||||||
url = Path.GetFullPath(url);
|
url = Path.GetFullPath(url);
|
||||||
this.rawText = File.ReadAllText(url);
|
this.rawText = await File.ReadAllTextAsync(url);
|
||||||
parserConfig.OriginalUrl = parserConfig.Url = new Uri(url).AbsoluteUri;
|
parserConfig.OriginalUrl = parserConfig.Url = new Uri(url).AbsoluteUri;
|
||||||
}
|
}
|
||||||
this.rawText = rawText.Trim();
|
this.rawText = rawText.Trim();
|
||||||
|
@ -134,22 +134,11 @@ namespace N_m3u8DL_RE.Parser
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await semaphore.WaitAsync();
|
await semaphore.WaitAsync();
|
||||||
int retryCount = 5; //增加重试
|
await RetryUtil.WebRequestRetryAsync(async () =>
|
||||||
reGet:
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
await extractor.RefreshPlayListAsync(streamSpecs);
|
await extractor.RefreshPlayListAsync(streamSpecs);
|
||||||
}
|
return true;
|
||||||
catch (Exception ex)
|
}, retryDelayMilliseconds: 1000, maxRetries: 5);
|
||||||
{
|
|
||||||
if (retryCount-- > 0)
|
|
||||||
{
|
|
||||||
Logger.WarnMarkUp($"[grey]Refresh Exception: {ex.Message.EscapeMarkup()} retryCount: {retryCount}[/]");
|
|
||||||
await Task.Delay(1000);
|
|
||||||
goto reGet;
|
|
||||||
}
|
|
||||||
else throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
|
@ -62,12 +62,10 @@ namespace N_m3u8DL_RE
|
||||||
static int GetOrder(StreamSpec streamSpec)
|
static int GetOrder(StreamSpec streamSpec)
|
||||||
{
|
{
|
||||||
if (streamSpec.Channels == null) return 0;
|
if (streamSpec.Channels == null) return 0;
|
||||||
else
|
|
||||||
{
|
|
||||||
var str = streamSpec.Channels.Split('/')[0];
|
var str = streamSpec.Channels.Split('/')[0];
|
||||||
return int.TryParse(str, out var order) ? order : 0;
|
return int.TryParse(str, out var order) ? order : 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static async Task DoWorkAsync(MyOption option)
|
static async Task DoWorkAsync(MyOption option)
|
||||||
{
|
{
|
||||||
|
@ -208,8 +206,12 @@ namespace N_m3u8DL_RE
|
||||||
|
|
||||||
//流提取器配置
|
//流提取器配置
|
||||||
var extractor = new StreamExtractor(parserConfig);
|
var extractor = new StreamExtractor(parserConfig);
|
||||||
extractor.LoadSourceFromUrl(url);
|
// 从链接加载内容
|
||||||
|
await RetryUtil.WebRequestRetryAsync(async () =>
|
||||||
|
{
|
||||||
|
await extractor.LoadSourceFromUrlAsync(url);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
//解析流信息
|
//解析流信息
|
||||||
var streams = await extractor.ExtractStreamsAsync();
|
var streams = await extractor.ExtractStreamsAsync();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue