From 6cc09fa373d1330cf1796349c68f7b1c0894641b Mon Sep 17 00:00:00 2001 From: Shingo Date: Wed, 7 Aug 2024 22:47:03 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=A0=81=E7=8E=87=E9=80=89?= =?UTF-8?q?=E6=8B=A9=E5=99=A8=E4=BB=A5=E5=8F=8A=E4=BF=AE=E5=A4=8D2?= =?UTF-8?q?=E5=A4=84bug=20(#427)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Prevent the ffmpeg-binary-path option from being accidentally overridden by the mux-after-done option. * Add bandwidth filter * Add bandwidth filter --- src/N_m3u8DL-RE.Common/Resource/StaticText.cs | 24 ++++++++++++------- src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs | 10 +++++++- src/N_m3u8DL-RE/Entity/StreamFilter.cs | 4 ++++ src/N_m3u8DL-RE/Util/FilterUtil.cs | 4 ++++ 4 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/N_m3u8DL-RE.Common/Resource/StaticText.cs b/src/N_m3u8DL-RE.Common/Resource/StaticText.cs index aaa4615..1265525 100644 --- a/src/N_m3u8DL-RE.Common/Resource/StaticText.cs +++ b/src/N_m3u8DL-RE.Common/Resource/StaticText.cs @@ -477,7 +477,7 @@ namespace N_m3u8DL_RE.Common.Resource zhCN: "通过正则表达式选择符合要求的视频流. 你能够以:分隔形式指定如下参数:\r\n\r\n" + "id=REGEX:lang=REGEX:name=REGEX:codecs=REGEX:res=REGEX:frame=REGEX\r\n" + "segsMin=number:segsMax=number:ch=REGEX:range=REGEX:url=REGEX\r\n" + - "plistDurMin=hms:plistDurMax=hms:role=string:for=FOR\r\n\r\n" + + "plistDurMin=hms:plistDurMax=hms:bwMin=int:bwMax=int:role=string:for=FOR\r\n\r\n" + "* for=FOR: 选择方式. best[number], worst[number], all (默认: best)\r\n\r\n" + "例如: \r\n" + "# 选择最佳视频\r\n" + @@ -486,11 +486,13 @@ namespace N_m3u8DL_RE.Common.Resource "-sv res=\"3840*\":codecs=hvc1:for=best\r\n" + "# 选择长度大于1小时20分钟30秒的视频\r\n" + "-sv plistDurMin=\"1h20m30s\":for=best\r\n" + - "-sv role=\"main\":for:best\r\n", + "-sv role=\"main\":for=best\r\n" + + "# 选择码率在800Kbps至1Mbps之间的视频\r\n" + + "-sv bwMin=800:bwMax=1000\r\n", zhTW: "通過正則表達式選擇符合要求的影片軌. 你能夠以:分隔形式指定如下參數:\r\n\r\n" + "id=REGEX:lang=REGEX:name=REGEX:codecs=REGEX:res=REGEX:frame=REGEX\r\n" + "segsMin=number:segsMax=number:ch=REGEX:range=REGEX:url=REGEX\r\n" + - "plistDurMin=hms:plistDurMax=hms:role=string:for=FOR\r\n\r\n" + + "plistDurMin=hms:plistDurMax=hms:bwMin=int:bwMax=int:role=string:for=FOR\r\n\r\n" + "* for=FOR: 選擇方式. best[number], worst[number], all (默認: best)\r\n\r\n" + "例如: \r\n" + "# 選擇最佳影片\r\n" + @@ -499,11 +501,13 @@ namespace N_m3u8DL_RE.Common.Resource "-sv res=\"3840*\":codecs=hvc1:for=best\r\n" + "# 選擇長度大於1小時20分鐘30秒的影片\r\n" + "-sv plistDurMin=\"1h20m30s\":for=best\r\n" + - "-sv role=\"main\":for:best\r\n", + "-sv role=\"main\":for=best\r\n" + + "# 選擇碼率在800Kbps至1Mbps之間的影片\r\n" + + "-sv bwMin=800:bwMax=1000\r\n", enUS: "Select video streams by regular expressions. OPTIONS is a colon separated list of:\r\n\r\n" + "id=REGEX:lang=REGEX:name=REGEX:codecs=REGEX:res=REGEX:frame=REGEX\r\n" + "segsMin=number:segsMax=number:ch=REGEX:range=REGEX:url=REGEX\r\n" + - "plistDurMin=hms:plistDurMax=hms:role=string:for=FOR\r\n\r\n" + + "plistDurMin=hms:plistDurMax=hms:bwMin=int:bwMax=int:role=string:for=FOR\r\n\r\n" + "* for=FOR: Select type. best[number], worst[number], all (Default: best)\r\n\r\n" + "Examples: \r\n" + "# select best video\r\n" + @@ -512,7 +516,9 @@ namespace N_m3u8DL_RE.Common.Resource "-sv res=\"3840*\":codecs=hvc1:for=best\r\n" + "# Select best video with duration longer than 1 hour 20 minutes 30 seconds\r\n" + "-sv plistDurMin=\"1h20m30s\":for=best\r\n" + - "-sv role=\"main\":for:best\r\n" + "-sv role=\"main\":for=best\r\n" + + "# Select video with bandwidth between 800Kbps and 1Mbps\r\n" + + "-sv bwMin=800:bwMax=1000\r\n" ), ["cmd_selectAudio"] = new TextContainer ( @@ -536,7 +542,7 @@ namespace N_m3u8DL_RE.Common.Resource "-sa lang=en:for=best\r\n" + "# 选择最佳的2条英语(或日语)音轨\r\n" + "-sa lang=\"ja|en\":for=best2\r\n" + - "-sa role=\"main\":for:best\r\n", + "-sa role=\"main\":for=best\r\n", zhTW: "通過正則表達式選擇符合要求的音軌. 參考 --select-video\r\n\r\n" + "例如: \r\n" + "# 選擇所有音訊\r\n" + @@ -545,7 +551,7 @@ namespace N_m3u8DL_RE.Common.Resource "-sa lang=en:for=best\r\n" + "# 選擇最佳的2條英語(或日語)音軌\r\n" + "-sa lang=\"ja|en\":for=best2\r\n" + - "-sa role=\"main\":for:best\r\n", + "-sa role=\"main\":for=best\r\n", enUS: "Select audio streams by regular expressions. ref --select-video\r\n\r\n" + "Examples: \r\n" + "# select all\r\n" + @@ -554,7 +560,7 @@ namespace N_m3u8DL_RE.Common.Resource "-sa lang=en:for=best\r\n" + "# select best 2, and language is ja or en\r\n" + "-sa lang=\"ja|en\":for=best2\r\n" + - "-sa role=\"main\":for:best\r\n" + "-sa role=\"main\":for=best\r\n" ), ["cmd_selectSubtitle"] = new TextContainer ( diff --git a/src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs b/src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs index ceb9777..e9311c4 100644 --- a/src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs +++ b/src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs @@ -369,6 +369,14 @@ namespace N_m3u8DL_RE.CommandLine if (!string.IsNullOrEmpty(plistDurMax)) streamFilter.PlaylistMaxDur = OtherUtil.ParseSeconds(plistDurMax); + var bwMin = p.GetValue("bwMin"); + if (!string.IsNullOrEmpty(bwMin)) + streamFilter.BandwidthMin = int.Parse(bwMin) * 1000; + + var bwMax = p.GetValue("bwMax"); + if (!string.IsNullOrEmpty(bwMax)) + streamFilter.BandwidthMax = int.Parse(bwMax) * 1000; + var role = p.GetValue("role"); if (System.Enum.TryParse(role, true, out RoleType roleType)) streamFilter.Role = roleType; @@ -566,7 +574,7 @@ namespace N_m3u8DL_RE.CommandLine option.MuxAfterDone = true; option.MuxOptions = muxAfterDoneValue; if (muxAfterDoneValue.UseMkvmerge) option.MkvmergeBinaryPath = muxAfterDoneValue.BinPath; - else option.FFmpegBinaryPath = muxAfterDoneValue.BinPath; + else option.FFmpegBinaryPath ??= muxAfterDoneValue.BinPath; } diff --git a/src/N_m3u8DL-RE/Entity/StreamFilter.cs b/src/N_m3u8DL-RE/Entity/StreamFilter.cs index 41191b3..d76d862 100644 --- a/src/N_m3u8DL-RE/Entity/StreamFilter.cs +++ b/src/N_m3u8DL-RE/Entity/StreamFilter.cs @@ -23,6 +23,8 @@ namespace N_m3u8DL_RE.Entity public long? SegmentsMaxCount { get; set; } public double? PlaylistMinDur { get; set; } public double? PlaylistMaxDur { get; set; } + public int? BandwidthMin { get; set; } + public int? BandwidthMax { get; set; } public RoleType? Role { get; set; } public string For { get; set; } = "best"; @@ -44,6 +46,8 @@ namespace N_m3u8DL_RE.Entity if (SegmentsMaxCount != null) sb.Append($"SegmentsMaxCount: {SegmentsMaxCount} "); if (PlaylistMinDur != null) sb.Append($"PlaylistMinDur: {PlaylistMinDur} "); if (PlaylistMaxDur != null) sb.Append($"PlaylistMaxDur: {PlaylistMaxDur} "); + if (BandwidthMin != null) sb.Append($"{nameof(BandwidthMin)}: {BandwidthMin} "); + if (BandwidthMax != null) sb.Append($"{nameof(BandwidthMax)}: {BandwidthMax} "); if (Role.HasValue) sb.Append($"Role: {Role} "); return sb.ToString() + $"For: {For}"; diff --git a/src/N_m3u8DL-RE/Util/FilterUtil.cs b/src/N_m3u8DL-RE/Util/FilterUtil.cs index 80a1a6b..ec06e64 100644 --- a/src/N_m3u8DL-RE/Util/FilterUtil.cs +++ b/src/N_m3u8DL-RE/Util/FilterUtil.cs @@ -46,6 +46,10 @@ namespace N_m3u8DL_RE.Util inputs = inputs.Where(i => i.Playlist?.TotalDuration > filter.PlaylistMinDur); if (filter.PlaylistMaxDur != null) inputs = inputs.Where(i => i.Playlist?.TotalDuration < filter.PlaylistMaxDur); + if (filter.BandwidthMin != null) + inputs = inputs.Where(i => i.Bandwidth >= filter.BandwidthMin); + if (filter.BandwidthMax != null) + inputs = inputs.Where(i => i.Bandwidth <= filter.BandwidthMax); if (filter.Role.HasValue) inputs = inputs.Where(i => i.Role == filter.Role);