支持限速功能 `--max-speed` #220
This commit is contained in:
parent
9ab8f3cf72
commit
eb85df8b4d
|
@ -34,6 +34,7 @@ namespace N_m3u8DL_RE.Common.Resource
|
|||
public static string cmd_ffmpegBinaryPath { get => GetText("cmd_ffmpegBinaryPath"); }
|
||||
public static string cmd_mkvmergeBinaryPath { get => GetText("cmd_mkvmergeBinaryPath"); }
|
||||
public static string cmd_baseUrl { get => GetText("cmd_baseUrl"); }
|
||||
public static string cmd_maxSpeed { get => GetText("cmd_maxSpeed"); }
|
||||
public static string cmd_adKeyword { get => GetText("cmd_adKeyword"); }
|
||||
public static string cmd_moreHelp { get => GetText("cmd_moreHelp"); }
|
||||
public static string cmd_header { get => GetText("cmd_header"); }
|
||||
|
|
|
@ -136,6 +136,12 @@ namespace N_m3u8DL_RE.Common.Resource
|
|||
zhTW: "設置BaseURL",
|
||||
enUS: "Set BaseURL"
|
||||
),
|
||||
["cmd_maxSpeed"] = new TextContainer
|
||||
(
|
||||
zhCN: "设置限速,单位支持 Mbps 或 Kbps,如:15M 100K",
|
||||
zhTW: "設置限速,單位支持 Mbps 或 Kbps,如:15M 100K",
|
||||
enUS: "Set speed limit, Mbps or Kbps, for example: 15M 100K."
|
||||
),
|
||||
["cmd_noDateInfo"] = new TextContainer
|
||||
(
|
||||
zhCN: "混流时不写入日期信息",
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace N_m3u8DL_RE.CommandLine
|
|||
{
|
||||
internal partial class CommandInvoker
|
||||
{
|
||||
public const string VERSION_INFO = "N_m3u8DL-RE (Beta version) 20230728";
|
||||
public const string VERSION_INFO = "N_m3u8DL-RE (Beta version) 20230730";
|
||||
|
||||
[GeneratedRegex("((best|worst)\\d*|all)")]
|
||||
private static partial Regex ForStrRegex();
|
||||
|
@ -58,6 +58,7 @@ namespace N_m3u8DL_RE.CommandLine
|
|||
private readonly static Option<bool> ConcurrentDownload = new(new string[] { "-mt", "--concurrent-download" }, description: ResString.cmd_concurrentDownload, getDefaultValue: () => false);
|
||||
private readonly static Option<bool> NoLog = new(new string[] { "--no-log" }, description: ResString.cmd_noLog, getDefaultValue: () => false);
|
||||
private readonly static Option<string[]?> AdKeywords = new(new string[] { "--ad-keyword" }, description: ResString.cmd_adKeyword) { ArgumentHelpName = "REG" };
|
||||
private readonly static Option<long?> MaxSpeed = new(new string[] { "-R", "--max-speed" }, description: ResString.cmd_maxSpeed, parseArgument: ParseSpeedLimit) { ArgumentHelpName = "SPEED" };
|
||||
|
||||
|
||||
//代理选项
|
||||
|
@ -102,6 +103,32 @@ namespace N_m3u8DL_RE.CommandLine
|
|||
private readonly static Option<StreamFilter?> DropAudioFilter = new(new string[] { "-da", "--drop-audio" }, description: ResString.cmd_dropAudio, parseArgument: ParseStreamFilter) { ArgumentHelpName = "OPTIONS" };
|
||||
private readonly static Option<StreamFilter?> DropSubtitleFilter = new(new string[] { "-ds", "--drop-subtitle" }, description: ResString.cmd_dropSubtitle, parseArgument: ParseStreamFilter) { ArgumentHelpName = "OPTIONS" };
|
||||
|
||||
/// <summary>
|
||||
/// 解析录制直播时长限制
|
||||
/// </summary>
|
||||
/// <param name="result"></param>
|
||||
/// <returns></returns>
|
||||
private static long? ParseSpeedLimit(ArgumentResult result)
|
||||
{
|
||||
var input = result.Tokens.First().Value.ToUpper();
|
||||
try
|
||||
{
|
||||
var reg = new Regex("([\\d\\\\.]+)(M|K)");
|
||||
if (!reg.IsMatch(input)) throw new ArgumentException();
|
||||
|
||||
var number = double.Parse(reg.Match(input).Groups[1].Value);
|
||||
if (reg.Match(input).Groups[2].Value == "M")
|
||||
return (long)(number * 1024 * 1024);
|
||||
else
|
||||
return (long)(number * 1024);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
result.ErrorMessage = "error in parse SpeedLimit: " + input;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解析用户定义的下载范围
|
||||
/// </summary>
|
||||
|
@ -502,6 +529,7 @@ namespace N_m3u8DL_RE.CommandLine
|
|||
NoDateInfo = bindingContext.ParseResult.GetValueForOption(NoDateInfo),
|
||||
NoLog = bindingContext.ParseResult.GetValueForOption(NoLog),
|
||||
AdKeywords = bindingContext.ParseResult.GetValueForOption(AdKeywords),
|
||||
MaxSpeed = bindingContext.ParseResult.GetValueForOption(MaxSpeed),
|
||||
};
|
||||
|
||||
if (bindingContext.ParseResult.HasOption(CustomHLSMethod)) option.CustomHLSMethod = bindingContext.ParseResult.GetValueForOption(CustomHLSMethod);
|
||||
|
@ -564,6 +592,7 @@ namespace N_m3u8DL_RE.CommandLine
|
|||
BinaryMerge, DelAfterDone, NoDateInfo, NoLog, WriteMetaJson, AppendUrlParams, ConcurrentDownload, Headers, /**SavePattern,**/ SubOnly, SubtitleFormat, AutoSubtitleFix,
|
||||
FFmpegBinaryPath,
|
||||
LogLevel, UILanguage, UrlProcessorArgs, Keys, KeyTextFile, DecryptionBinaryPath, UseShakaPackager, MP4RealTimeDecryption,
|
||||
MaxSpeed,
|
||||
MuxAfterDone,
|
||||
CustomHLSMethod, CustomHLSKey, CustomHLSIv, UseSystemProxy, CustomProxy, CustomRange, TaskStartAt,
|
||||
LivePerformAsVod, LiveRealTimeMerge, LiveKeepSegments, LivePipeMux, LiveFixVttByAudio, LiveRecordLimit, LiveWaitTime, LiveTakeCount,
|
||||
|
|
|
@ -21,6 +21,10 @@ namespace N_m3u8DL_RE.CommandLine
|
|||
/// </summary>
|
||||
public string[]? AdKeywords { get; set; }
|
||||
/// <summary>
|
||||
/// See: <see cref="CommandInvoker.MaxSpeed"/>.
|
||||
/// </summary>
|
||||
public long? MaxSpeed { get; set; }
|
||||
/// <summary>
|
||||
/// See: <see cref="CommandInvoker.Keys"/>.
|
||||
/// </summary>
|
||||
public string[]? Keys { get; set; }
|
||||
|
|
|
@ -662,6 +662,11 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
var description = item.ToShortShortString();
|
||||
var task = ctx.AddTask(description, autoStart: false);
|
||||
SpeedContainerDic[task.Id] = new SpeedContainer(); //速度计算
|
||||
//限速设置
|
||||
if (DownloaderConfig.MyOptions.MaxSpeed != null)
|
||||
{
|
||||
SpeedContainerDic[task.Id].SpeedLimit = DownloaderConfig.MyOptions.MaxSpeed.Value;
|
||||
}
|
||||
return (item, task);
|
||||
}).ToDictionary(item => item.item, item => item.task);
|
||||
|
||||
|
|
|
@ -840,6 +840,11 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
{
|
||||
var task = ctx.AddTask(item.ToShortShortString(), autoStart: false, maxValue: 0);
|
||||
SpeedContainerDic[task.Id] = new SpeedContainer(); //速度计算
|
||||
//限速设置
|
||||
if (DownloaderConfig.MyOptions.MaxSpeed != null)
|
||||
{
|
||||
SpeedContainerDic[task.Id].SpeedLimit = DownloaderConfig.MyOptions.MaxSpeed.Value;
|
||||
}
|
||||
LastFileNameDic[task.Id] = "";
|
||||
RecordLimitReachedDic[task.Id] = false;
|
||||
DateTimeDic[task.Id] = 0L;
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace N_m3u8DL_RE.Entity
|
|||
{
|
||||
public bool SingleSegment { get; set; } = false;
|
||||
public long NowSpeed { get; set; } = 0L; //当前每秒速度
|
||||
public long SpeedLimit { get; set; } = long.MaxValue; //限速设置
|
||||
public long? ResponseLength { get; set; }
|
||||
public long RDownloaded { get => _Rdownloaded; }
|
||||
private int _zeroSpeedCount = 0;
|
||||
|
|
|
@ -120,6 +120,11 @@ namespace N_m3u8DL_RE.Util
|
|||
{
|
||||
speedContainer.Add(size);
|
||||
await stream.WriteAsync(buffer, 0, size);
|
||||
//限速策略
|
||||
while (speedContainer.Downloaded > speedContainer.SpeedLimit)
|
||||
{
|
||||
await Task.Delay(1);
|
||||
}
|
||||
}
|
||||
|
||||
return new DownloadResult()
|
||||
|
|
Loading…
Reference in New Issue