连续20秒速度为0时,重试
This commit is contained in:
parent
b032b46bd3
commit
9211e185fd
|
@ -32,7 +32,7 @@ namespace N_m3u8DL_RE.Common.Util
|
|||
|
||||
public static readonly HttpClient AppHttpClient = new(HttpClientHandler)
|
||||
{
|
||||
Timeout = TimeSpan.FromMinutes(2)
|
||||
Timeout = TimeSpan.FromSeconds(100)
|
||||
};
|
||||
|
||||
private static async Task<HttpResponseMessage> DoGetAsync(string url, Dictionary<string, string>? headers = null)
|
||||
|
|
|
@ -13,10 +13,11 @@ namespace N_m3u8DL_RE.Column
|
|||
{
|
||||
internal sealed class DownloadSpeedColumn : ProgressColumn
|
||||
{
|
||||
private long _stopSpeed = 0;
|
||||
private ConcurrentDictionary<int, string> DateTimeStringDic = new();
|
||||
private ConcurrentDictionary<int, string> SpeedDic = new();
|
||||
protected override bool NoWrap => true;
|
||||
public ConcurrentDictionary<int, SpeedContainer> SpeedContainerDic { get; set; }
|
||||
private ConcurrentDictionary<int, SpeedContainer> SpeedContainerDic { get; set; }
|
||||
|
||||
public DownloadSpeedColumn(ConcurrentDictionary<int, SpeedContainer> SpeedContainerDic)
|
||||
{
|
||||
|
@ -41,6 +42,9 @@ namespace N_m3u8DL_RE.Column
|
|||
if (DateTimeStringDic.TryGetValue(taskId, out var oldTime) && oldTime != now)
|
||||
{
|
||||
SpeedDic[taskId] = FormatFileSize(speedContainer.Downloaded);
|
||||
//速度为0,计数增加
|
||||
if (speedContainer.Downloaded <= _stopSpeed) { speedContainer.AddLowSpeedCount(); SpeedDic[taskId] += $"({speedContainer.LowSpeedCount})"; }
|
||||
else speedContainer.ResetLowSpeedCount();
|
||||
speedContainer.Reset();
|
||||
}
|
||||
DateTimeStringDic[taskId] = now;
|
||||
|
|
|
@ -406,7 +406,7 @@ namespace N_m3u8DL_RE.CommandLine
|
|||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
var rootCommand = new RootCommand("N_m3u8DL-RE (Beta version) 20220922")
|
||||
var rootCommand = new RootCommand("N_m3u8DL-RE (Beta version) 20220925")
|
||||
{
|
||||
Input, TmpDir, SaveDir, SaveName, BaseUrl, ThreadCount, DownloadRetryCount, AutoSelect, SkipMerge, SkipDownload, CheckSegmentsCount,
|
||||
BinaryMerge, DelAfterDone, WriteMetaJson, AppendUrlParams, ConcurrentDownload, Headers, /**SavePattern,**/ SubOnly, SubtitleFormat, AutoSubtitleFix,
|
||||
|
|
|
@ -14,12 +14,25 @@ namespace N_m3u8DL_RE.Entity
|
|||
public bool SingleSegment { get; set; } = false;
|
||||
public long? ResponseLength { get; set; }
|
||||
public long RDownloaded { get; set; } = 0L;
|
||||
private int _zeroSpeedCount = 0;
|
||||
public int LowSpeedCount { get => _zeroSpeedCount; }
|
||||
public bool ShouldStop { get => LowSpeedCount >= 20; }
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
private long _downloaded = 0;
|
||||
public long Downloaded { get => _downloaded; }
|
||||
|
||||
public int AddLowSpeedCount()
|
||||
{
|
||||
return Interlocked.Add(ref _zeroSpeedCount, 1);
|
||||
}
|
||||
|
||||
public int ResetLowSpeedCount()
|
||||
{
|
||||
return Interlocked.Exchange(ref _zeroSpeedCount, 0);
|
||||
}
|
||||
|
||||
public long Add(long size)
|
||||
{
|
||||
if (SingleSegment) RDownloaded += size;
|
||||
|
@ -34,6 +47,7 @@ namespace N_m3u8DL_RE.Entity
|
|||
public void ResetVars()
|
||||
{
|
||||
Reset();
|
||||
ResetLowSpeedCount();
|
||||
SingleSegment = false;
|
||||
ResponseLength = null;
|
||||
RDownloaded = 0L;
|
||||
|
|
|
@ -31,37 +31,60 @@ namespace N_m3u8DL_RE.Util
|
|||
}
|
||||
}
|
||||
Logger.Debug(request.Headers.ToString());
|
||||
using var response = await AppHttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
|
||||
if (response.StatusCode == HttpStatusCode.Found || response.StatusCode == HttpStatusCode.Moved)
|
||||
CancellationTokenSource cancellationTokenSource = new(); //取消下载
|
||||
using var watcher = Task.Factory.StartNew(async () =>
|
||||
{
|
||||
HttpResponseHeaders respHeaders = response.Headers;
|
||||
Logger.Debug(respHeaders.ToString());
|
||||
if (respHeaders != null && respHeaders.Location != null)
|
||||
while (true)
|
||||
{
|
||||
var redirectedUrl = respHeaders.Location.AbsoluteUri;
|
||||
return await DownloadToFileAsync(redirectedUrl, path, speedContainer, headers, fromPosition, toPosition);
|
||||
if (speedContainer == null) break;
|
||||
if (speedContainer.ShouldStop)
|
||||
{
|
||||
cancellationTokenSource.Cancel();
|
||||
speedContainer.ResetLowSpeedCount();
|
||||
Logger.WarnMarkUp("Cancel...");
|
||||
break;
|
||||
}
|
||||
await Task.Delay(500);
|
||||
}
|
||||
}
|
||||
response.EnsureSuccessStatusCode();
|
||||
var contentLength = response.Content.Headers.ContentLength;
|
||||
if (speedContainer.SingleSegment) speedContainer.ResponseLength = contentLength;
|
||||
|
||||
using var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
using var responseStream = await response.Content.ReadAsStreamAsync();
|
||||
var buffer = new byte[16 * 1024];
|
||||
var size = 0;
|
||||
while ((size = await responseStream.ReadAsync(buffer)) > 0)
|
||||
});
|
||||
try
|
||||
{
|
||||
speedContainer.Add(size);
|
||||
await stream.WriteAsync(buffer, 0, size);
|
||||
}
|
||||
using var response = await AppHttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationTokenSource.Token);
|
||||
if (response.StatusCode == HttpStatusCode.Found || response.StatusCode == HttpStatusCode.Moved)
|
||||
{
|
||||
HttpResponseHeaders respHeaders = response.Headers;
|
||||
Logger.Debug(respHeaders.ToString());
|
||||
if (respHeaders != null && respHeaders.Location != null)
|
||||
{
|
||||
var redirectedUrl = respHeaders.Location.AbsoluteUri;
|
||||
return await DownloadToFileAsync(redirectedUrl, path, speedContainer, headers, fromPosition, toPosition);
|
||||
}
|
||||
}
|
||||
response.EnsureSuccessStatusCode();
|
||||
var contentLength = response.Content.Headers.ContentLength;
|
||||
if (speedContainer.SingleSegment) speedContainer.ResponseLength = contentLength;
|
||||
|
||||
return new DownloadResult()
|
||||
using var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
using var responseStream = await response.Content.ReadAsStreamAsync(cancellationTokenSource.Token);
|
||||
var buffer = new byte[16 * 1024];
|
||||
var size = 0;
|
||||
while ((size = await responseStream.ReadAsync(buffer, cancellationTokenSource.Token)) > 0)
|
||||
{
|
||||
speedContainer.Add(size);
|
||||
await stream.WriteAsync(buffer, 0, size);
|
||||
}
|
||||
|
||||
return new DownloadResult()
|
||||
{
|
||||
ActualContentLength = stream.Length,
|
||||
RespContentLength = contentLength,
|
||||
ActualFilePath = path
|
||||
};
|
||||
}
|
||||
catch (OperationCanceledException oce) when (oce.CancellationToken == cancellationTokenSource.Token)
|
||||
{
|
||||
ActualContentLength = stream.Length,
|
||||
RespContentLength = contentLength,
|
||||
ActualFilePath = path
|
||||
};
|
||||
throw new Exception("Download speed too slow!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue