支持通过时长筛选 `plistDurMin`
This commit is contained in:
parent
724a5c9fa2
commit
43cb264374
|
@ -386,31 +386,40 @@ namespace N_m3u8DL_RE.Common.Resource
|
|||
(
|
||||
zhCN: "通过正则表达式选择符合要求的视频流. 你能够以:分隔形式指定如下参数:\r\n\r\n" +
|
||||
"id=REGEX:lang=REGEX:name=REGEX:codec=REGEX:res=REGEX:frame=REGEX\r\n" +
|
||||
"segsMin=number:segsMax=number:ch=REGEX:range=REGEX:url=REGEX:for=FOR\r\n\r\n" +
|
||||
"segsMin=number:segsMax=number:ch=REGEX:range=REGEX:url=REGEX\r\n" +
|
||||
"plistDurMin=hms:plistDurMax=hms:for=FOR\r\n\r\n" +
|
||||
"* for=FOR: 选择方式. best[number], worst[number], all (默认: best)\r\n\r\n" +
|
||||
"例如: \r\n" +
|
||||
"# 选择最佳视频\r\n" +
|
||||
"-sv best\r\n" +
|
||||
"# 选择4K+HEVC视频\r\n" +
|
||||
"-sv res=\"3840*\":codec=hvc1:for=best\r\n",
|
||||
"-sv res=\"3840*\":codec=hvc1:for=best\r\n" +
|
||||
"# 选择长度大于1小时20分钟30秒的视频\r\n" +
|
||||
"-sv plistDurMin=\"1h20m30s\":for=best\r\n",
|
||||
zhTW: "通過正則表達式選擇符合要求的影片軌. 你能夠以:分隔形式指定如下參數:\r\n\r\n" +
|
||||
"id=REGEX:lang=REGEX:name=REGEX:codec=REGEX:res=REGEX:frame=REGEX\r\n" +
|
||||
"segsMin=number:segsMax=number:ch=REGEX:range=REGEX:url=REGEX:for=FOR\r\n\r\n" +
|
||||
"segsMin=number:segsMax=number:ch=REGEX:range=REGEX:url=REGEX\r\n" +
|
||||
"plistDurMin=hms:plistDurMax=hms:for=FOR\r\n\r\n" +
|
||||
"* for=FOR: 選擇方式. best[number], worst[number], all (默認: best)\r\n\r\n" +
|
||||
"例如: \r\n" +
|
||||
"# 選擇最佳影片\r\n" +
|
||||
"-sv best\r\n" +
|
||||
"# 選擇4K+HEVC影片\r\n" +
|
||||
"-sv res=\"3840*\":codec=hvc1:for=best\r\n",
|
||||
"-sv res=\"3840*\":codec=hvc1:for=best\r\n" +
|
||||
"# 選擇長度大於1小時20分鐘30秒的影片\r\n" +
|
||||
"-sv plistDurMin=\"1h20m30s\":for=best\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:codec=REGEX:res=REGEX:frame=REGEX\r\n" +
|
||||
"segsMin=number:segsMax=number:ch=REGEX:range=REGEX:url=REGEX:for=FOR\r\n\r\n" +
|
||||
"segsMin=number:segsMax=number:ch=REGEX:range=REGEX:url=REGEX\r\n" +
|
||||
"plistDurMin=hms:plistDurMax=hms: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" +
|
||||
"-sv best\r\n" +
|
||||
"# select 4K+HEVC video\r\n" +
|
||||
"-sv res=\"3840*\":codec=hvc1:for=best\r\n"
|
||||
"-sv res=\"3840*\":codec=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"
|
||||
),
|
||||
["cmd_selectAudio"] = new TextContainer
|
||||
(
|
||||
|
|
|
@ -274,6 +274,14 @@ namespace N_m3u8DL_RE.CommandLine
|
|||
if (!string.IsNullOrEmpty(segsMax))
|
||||
streamFilter.SegmentsMaxCount = long.Parse(segsMax);
|
||||
|
||||
var plistDurMin = p.GetValue("plistDurMin");
|
||||
if (!string.IsNullOrEmpty(plistDurMin))
|
||||
streamFilter.PlaylistMinDur = OtherUtil.ParseSeconds(plistDurMin);
|
||||
|
||||
var plistDurMax = p.GetValue("plistDurMax");
|
||||
if (!string.IsNullOrEmpty(plistDurMax))
|
||||
streamFilter.PlaylistMaxDur = OtherUtil.ParseSeconds(plistDurMax);
|
||||
|
||||
return streamFilter;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@ namespace N_m3u8DL_RE.Entity
|
|||
public Regex? UrlReg { get; set; }
|
||||
public long? SegmentsMinCount { get; set; }
|
||||
public long? SegmentsMaxCount { get; set; }
|
||||
public double? PlaylistMinDur { get; set; }
|
||||
public double? PlaylistMaxDur { get; set; }
|
||||
|
||||
public string For { get; set; } = "best";
|
||||
}
|
||||
|
|
|
@ -40,6 +40,10 @@ namespace N_m3u8DL_RE.Util
|
|||
inputs = inputs.Where(i => i.SegmentsCount < filter.SegmentsMaxCount);
|
||||
if (filter.SegmentsMinCount != null && inputs.All(i => i.SegmentsCount > 0))
|
||||
inputs = inputs.Where(i => i.SegmentsCount > filter.SegmentsMinCount);
|
||||
if (filter.PlaylistMinDur != null)
|
||||
inputs = inputs.Where(i => i.Playlist?.TotalDuration > filter.PlaylistMinDur);
|
||||
if (filter.PlaylistMaxDur != null)
|
||||
inputs = inputs.Where(i => i.Playlist?.TotalDuration < filter.PlaylistMaxDur);
|
||||
|
||||
var bestNumberStr = filter.For.Replace("best", "");
|
||||
var worstNumberStr = filter.For.Replace("worst", "");
|
||||
|
|
|
@ -4,6 +4,7 @@ using N_m3u8DL_RE.Enum;
|
|||
using System.CommandLine;
|
||||
using System.IO.Compression;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace N_m3u8DL_RE.Util
|
||||
{
|
||||
|
@ -94,6 +95,30 @@ namespace N_m3u8DL_RE.Util
|
|||
return new TimeSpan(days, hours, mins, secs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从1h3m20s解析出总秒数
|
||||
/// </summary>
|
||||
/// <param name="timeStr"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
public static double ParseSeconds(string timeStr)
|
||||
{
|
||||
var pattern = new Regex(@"^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$");
|
||||
|
||||
var match = pattern.Match(timeStr);
|
||||
|
||||
if (!match.Success)
|
||||
{
|
||||
throw new ArgumentException("时间格式无效");
|
||||
}
|
||||
|
||||
int hours = match.Groups[1].Success ? int.Parse(match.Groups[1].Value) : 0;
|
||||
int minutes = match.Groups[2].Success ? int.Parse(match.Groups[2].Value) : 0;
|
||||
int seconds = match.Groups[3].Success ? int.Parse(match.Groups[3].Value) : 0;
|
||||
|
||||
return hours * 3600 + minutes * 60 + seconds;
|
||||
}
|
||||
|
||||
//若该文件夹为空,删除,同时判断其父文件夹,直到遇到根目录或不为空的目录
|
||||
public static void SafeDeleteDir(string dirPath)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue