From a8bc97841e826d11ead1d88a0a720473c09a1743 Mon Sep 17 00:00:00 2001 From: nilaoda Date: Wed, 21 Dec 2022 17:33:38 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E4=BC=98=E5=8C=96Group=20ID=E5=90=AB?= =?UTF-8?q?=E6=9C=89=E7=89=B9=E6=AE=8A=E7=AC=A6=E5=8F=B7=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/N_m3u8DL-RE/DownloadManager/HTTPLiveRecordManager.cs | 2 +- src/N_m3u8DL-RE/DownloadManager/SimpleDownloadManager.cs | 2 +- src/N_m3u8DL-RE/DownloadManager/SimpleLiveRecordManager2.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/N_m3u8DL-RE/DownloadManager/HTTPLiveRecordManager.cs b/src/N_m3u8DL-RE/DownloadManager/HTTPLiveRecordManager.cs index b8623d47..c568a93a 100644 --- a/src/N_m3u8DL-RE/DownloadManager/HTTPLiveRecordManager.cs +++ b/src/N_m3u8DL-RE/DownloadManager/HTTPLiveRecordManager.cs @@ -57,7 +57,7 @@ private async Task RecordStreamAsync(StreamSpec streamSpec, ProgressTask t task.StartTask(); var name = streamSpec.ToShortString(); - var dirName = $"{DownloaderConfig.MyOptions.SaveName ?? NowDateTime.ToString("yyyy-MM-dd_HH-mm-ss")}_{task.Id}_{streamSpec.GroupId}_{streamSpec.Codecs}_{streamSpec.Bandwidth}_{streamSpec.Language}"; + var dirName = $"{DownloaderConfig.MyOptions.SaveName ?? NowDateTime.ToString("yyyy-MM-dd_HH-mm-ss")}_{task.Id}_{OtherUtil.GetValidFileName(streamSpec.GroupId ?? "", "-")}_{streamSpec.Codecs}_{streamSpec.Bandwidth}_{streamSpec.Language}"; var saveDir = DownloaderConfig.MyOptions.SaveDir ?? Environment.CurrentDirectory; var saveName = DownloaderConfig.MyOptions.SaveName != null ? $"{DownloaderConfig.MyOptions.SaveName}.{streamSpec.Language}".TrimEnd('.') : dirName; diff --git a/src/N_m3u8DL-RE/DownloadManager/SimpleDownloadManager.cs b/src/N_m3u8DL-RE/DownloadManager/SimpleDownloadManager.cs index eef24699..b3ec3cd4 100644 --- a/src/N_m3u8DL-RE/DownloadManager/SimpleDownloadManager.cs +++ b/src/N_m3u8DL-RE/DownloadManager/SimpleDownloadManager.cs @@ -110,7 +110,7 @@ private async Task DownloadStreamAsync(StreamSpec streamSpec, ProgressTask if (segments.Count() == 1) speedContainer.SingleSegment = true; var type = streamSpec.MediaType ?? Common.Enum.MediaType.VIDEO; - var dirName = $"{DownloaderConfig.MyOptions.SaveName ?? NowDateTime.ToString("yyyy-MM-dd_HH-mm-ss")}_{task.Id}_{streamSpec.GroupId}_{streamSpec.Codecs}_{streamSpec.Bandwidth}_{streamSpec.Language}"; + var dirName = $"{DownloaderConfig.MyOptions.SaveName ?? NowDateTime.ToString("yyyy-MM-dd_HH-mm-ss")}_{task.Id}_{OtherUtil.GetValidFileName(streamSpec.GroupId ?? "", "-")}_{streamSpec.Codecs}_{streamSpec.Bandwidth}_{streamSpec.Language}"; var tmpDir = Path.Combine(DownloaderConfig.MyOptions.TmpDir ?? Environment.CurrentDirectory, dirName); var saveDir = DownloaderConfig.MyOptions.SaveDir ?? Environment.CurrentDirectory; var saveName = DownloaderConfig.MyOptions.SaveName != null ? $"{DownloaderConfig.MyOptions.SaveName}.{streamSpec.Language}".TrimEnd('.') : dirName; diff --git a/src/N_m3u8DL-RE/DownloadManager/SimpleLiveRecordManager2.cs b/src/N_m3u8DL-RE/DownloadManager/SimpleLiveRecordManager2.cs index 6f4eaf88..caf00954 100644 --- a/src/N_m3u8DL-RE/DownloadManager/SimpleLiveRecordManager2.cs +++ b/src/N_m3u8DL-RE/DownloadManager/SimpleLiveRecordManager2.cs @@ -181,7 +181,7 @@ private async Task RecordStreamAsync(StreamSpec streamSpec, ProgressTask t var name = streamSpec.ToShortString(); var type = streamSpec.MediaType ?? Common.Enum.MediaType.VIDEO; - var dirName = $"{DownloaderConfig.MyOptions.SaveName ?? NowDateTime.ToString("yyyy-MM-dd_HH-mm-ss")}_{task.Id}_{streamSpec.GroupId}_{streamSpec.Codecs}_{streamSpec.Bandwidth}_{streamSpec.Language}"; + var dirName = $"{DownloaderConfig.MyOptions.SaveName ?? NowDateTime.ToString("yyyy-MM-dd_HH-mm-ss")}_{task.Id}_{OtherUtil.GetValidFileName(streamSpec.GroupId ?? "", "-")}_{streamSpec.Codecs}_{streamSpec.Bandwidth}_{streamSpec.Language}"; var tmpDir = Path.Combine(DownloaderConfig.MyOptions.TmpDir ?? Environment.CurrentDirectory, dirName); var saveDir = DownloaderConfig.MyOptions.SaveDir ?? Environment.CurrentDirectory; var saveName = DownloaderConfig.MyOptions.SaveName != null ? $"{DownloaderConfig.MyOptions.SaveName}.{streamSpec.Language}".TrimEnd('.') : dirName; From 418547d5a26e999588c68812aab6e7439de630e8 Mon Sep 17 00:00:00 2001 From: nilaoda Date: Wed, 21 Dec 2022 18:37:53 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E6=9B=BF=E6=8D=A2=E5=92=8C=E7=BB=84=E8=A3=85URL=E7=9A=84?= =?UTF-8?q?=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Extractor/DASHExtractor2.cs | 26 +++++++++++-------- src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs | 2 +- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/N_m3u8DL-RE.Parser/Extractor/DASHExtractor2.cs b/src/N_m3u8DL-RE.Parser/Extractor/DASHExtractor2.cs index 81a52adf..055eeea7 100644 --- a/src/N_m3u8DL-RE.Parser/Extractor/DASHExtractor2.cs +++ b/src/N_m3u8DL-RE.Parser/Extractor/DASHExtractor2.cs @@ -312,13 +312,14 @@ public async Task> ExtractStreamsAsync(string rawText) var initialization = segmentTemplate.Attribute("initialization")?.Value ?? segmentTemplateOuter.Attribute("initialization")?.Value; if (initialization != null) { - var initUrl = ParserUtil.ReplaceVars(ParserUtil.CombineURL(segBaseUrl, initialization), varDic); + var _init = ParserUtil.ReplaceVars(initialization, varDic); + var initUrl = ParserUtil.CombineURL(segBaseUrl, _init); streamSpec.Playlist.MediaInit = new MediaSegment(); streamSpec.Playlist.MediaInit.Index = -1; //便于排序 streamSpec.Playlist.MediaInit.Url = initUrl; } //处理分片 - var media = segmentTemplate.Attribute("media")?.Value ?? segmentTemplateOuter.Attribute("media")?.Value; + var mediaTemplate = segmentTemplate.Attribute("media")?.Value ?? segmentTemplateOuter.Attribute("media")?.Value; var segmentTimeline = segmentTemplate.Elements().Where(e => e.Name.LocalName == "SegmentTimeline").FirstOrDefault(); if (segmentTimeline != null) { @@ -340,11 +341,12 @@ public async Task> ExtractStreamsAsync(string rawText) var _repeatCount = Convert.ToInt64(_repeatCountStr); varDic[DASHTags.TemplateTime] = currentTime; varDic[DASHTags.TemplateNumber] = segNumber++; - var oriUrl = ParserUtil.CombineURL(segBaseUrl, media!); - var mediaUrl = ParserUtil.ReplaceVars(oriUrl, varDic); + var hasTime = mediaTemplate!.Contains(DASHTags.TemplateTime); + var media = ParserUtil.ReplaceVars(mediaTemplate!, varDic); + var mediaUrl = ParserUtil.CombineURL(segBaseUrl, media!); MediaSegment mediaSegment = new(); mediaSegment.Url = mediaUrl; - if (oriUrl.Contains(DASHTags.TemplateTime)) + if (hasTime) mediaSegment.NameFromVar = currentTime.ToString(); mediaSegment.Duration = _duration / (double)timescale; mediaSegment.Index = segIndex++; @@ -360,12 +362,13 @@ public async Task> ExtractStreamsAsync(string rawText) MediaSegment _mediaSegment = new(); varDic[DASHTags.TemplateTime] = currentTime; varDic[DASHTags.TemplateNumber] = segNumber++; - var _oriUrl = ParserUtil.CombineURL(segBaseUrl, media!); - var _mediaUrl = ParserUtil.ReplaceVars(_oriUrl, varDic); + var _hashTime = mediaTemplate!.Contains(DASHTags.TemplateTime); + var _media = ParserUtil.ReplaceVars(mediaTemplate!, varDic); + var _mediaUrl = ParserUtil.CombineURL(segBaseUrl, _media); _mediaSegment.Url = _mediaUrl; _mediaSegment.Index = segIndex++; _mediaSegment.Duration = _duration / (double)timescale; - if (_oriUrl.Contains(DASHTags.TemplateTime)) + if (_hashTime) _mediaSegment.NameFromVar = currentTime.ToString(); streamSpec.Playlist.MediaParts[0].MediaSegments.Add(_mediaSegment); } @@ -396,11 +399,12 @@ public async Task> ExtractStreamsAsync(string rawText) for (long index = startNumber, segIndex = 0; index < startNumber + totalNumber; index++, segIndex++) { varDic[DASHTags.TemplateNumber] = index; - var oriUrl = ParserUtil.CombineURL(segBaseUrl, media!); - var mediaUrl = ParserUtil.ReplaceVars(oriUrl, varDic); + var hasNumber = mediaTemplate!.Contains(DASHTags.TemplateNumber); + var media = ParserUtil.ReplaceVars(mediaTemplate!, varDic); + var mediaUrl = ParserUtil.CombineURL(segBaseUrl, media!); MediaSegment mediaSegment = new(); mediaSegment.Url = mediaUrl; - if (oriUrl.Contains(DASHTags.TemplateNumber)) + if (hasNumber) mediaSegment.NameFromVar = index.ToString(); mediaSegment.Index = isLive ? index : segIndex; //直播直接用startNumber mediaSegment.Duration = duration / (double)timescale; diff --git a/src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs b/src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs index feea8c70..d21e89d3 100644 --- a/src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs +++ b/src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs @@ -18,7 +18,7 @@ namespace N_m3u8DL_RE.CommandLine { internal partial class CommandInvoker { - public const string VERSION_INFO = "N_m3u8DL-RE (Beta version) 20221220"; + public const string VERSION_INFO = "N_m3u8DL-RE (Beta version) 20221221"; [GeneratedRegex("((best|worst)\\d*|all)")] private static partial Regex ForStrRegex(); From 1b1cef9a94737a2a4d67c5c8d3bc8a541265e6c9 Mon Sep 17 00:00:00 2001 From: nilaoda Date: Wed, 11 Jan 2023 22:57:26 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E4=BC=98=E5=8C=96Master=E7=9A=84=E5=88=B7?= =?UTF-8?q?=E6=96=B0=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Extractor/HLSExtractor.cs | 58 +++++++++++-------- src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs | 2 +- 2 files changed, 34 insertions(+), 26 deletions(-) diff --git a/src/N_m3u8DL-RE.Parser/Extractor/HLSExtractor.cs b/src/N_m3u8DL-RE.Parser/Extractor/HLSExtractor.cs index 1b9a3c83..0bb55fde 100644 --- a/src/N_m3u8DL-RE.Parser/Extractor/HLSExtractor.cs +++ b/src/N_m3u8DL-RE.Parser/Extractor/HLSExtractor.cs @@ -23,7 +23,6 @@ internal class HLSExtractor : IExtractor private string BaseUrl = string.Empty; private string M3u8Content = string.Empty; private bool MasterM3u8Flag = false; - private bool FirstFetchFlag = true; public ParserConfig ParserConfig { get; set; } @@ -84,14 +83,10 @@ public string PreProcessUrl(string url) return url; } - private bool IsMaster() - { - MasterM3u8Flag = M3u8Content.Contains(HLSTags.ext_x_stream_inf); - return MasterM3u8Flag; - } - private async Task> ParseMasterListAsync() { + MasterM3u8Flag = true; + List streams = new List(); using StringReader sr = new StringReader(M3u8Content); @@ -475,7 +470,7 @@ public async Task> ExtractStreamsAsync(string rawText) { this.M3u8Content = rawText; this.PreProcessContent(); - if (IsMaster()) + if (M3u8Content.Contains(HLSTags.ext_x_stream_inf)) { Logger.Warn(ResString.masterM3u8Found); var lists = await ParseMasterListAsync(); @@ -523,30 +518,44 @@ private async Task LoadM3u8FromUrlAsync(string url) this.PreProcessContent(); } - public async Task FetchPlayListAsync(List lists) + /// + /// 从Master链接中刷新各个流的URL + /// + /// + /// + private async Task RefreshUrlFromMaster(List lists) { - //首次加载不需要刷新URL - if (!FirstFetchFlag && MasterM3u8Flag) + //重新加载master m3u8, 刷新选中流的URL + await LoadM3u8FromUrlAsync(ParserConfig.Url); + var newStreams = await ParseMasterListAsync(); + newStreams = newStreams.DistinctBy(p => p.Url).ToList(); + foreach (var l in lists) { - //重新加载master m3u8, 刷新选中流的URL - await LoadM3u8FromUrlAsync(ParserConfig.Url); - var newStreams = await ParseMasterListAsync(); - newStreams = newStreams.DistinctBy(p => p.Url).ToList(); - foreach (var l in lists) + var match = newStreams.Where(n => n.ToShortString() == l.ToShortString()); + if (match.Any()) { - var match = newStreams.Where(n => n.ToShortString() == l.ToShortString()); - if (match.Any()) - { - Logger.DebugMarkUp($"{l.Url} => {match.First().Url}"); - l.Url = match.First().Url; - } + Logger.DebugMarkUp($"{l.Url} => {match.First().Url}"); + l.Url = match.First().Url; } } + } + public async Task FetchPlayListAsync(List lists) + { for (int i = 0; i < lists.Count; i++) { - //重新加载m3u8 - await LoadM3u8FromUrlAsync(lists[i].Url!); + try + { + //直接重新加载m3u8 + await LoadM3u8FromUrlAsync(lists[i].Url!); + } + catch (HttpRequestException) when (MasterM3u8Flag == true) + { + Logger.WarnMarkUp("Can not load m3u8. Try refreshing url from master url..."); + //当前URL无法加载 尝试从Master链接中刷新URL + await RefreshUrlFromMaster(lists); + await LoadM3u8FromUrlAsync(lists[i].Url!); + } var newPlaylist = await ParseListAsync(); if (lists[i].Playlist?.MediaInit != null) @@ -570,7 +579,6 @@ public async Task FetchPlayListAsync(List lists) public async Task RefreshPlayListAsync(List streamSpecs) { - FirstFetchFlag = false; await FetchPlayListAsync(streamSpecs); } } diff --git a/src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs b/src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs index d21e89d3..66c9382a 100644 --- a/src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs +++ b/src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs @@ -18,7 +18,7 @@ namespace N_m3u8DL_RE.CommandLine { internal partial class CommandInvoker { - public const string VERSION_INFO = "N_m3u8DL-RE (Beta version) 20221221"; + public const string VERSION_INFO = "N_m3u8DL-RE (Beta version) 20230111"; [GeneratedRegex("((best|worst)\\d*|all)")] private static partial Regex ForStrRegex(); From 7014cba7703b5b0dce869e142a0225640e94f3ec Mon Sep 17 00:00:00 2001 From: nilaoda Date: Wed, 11 Jan 2023 23:00:52 +0800 Subject: [PATCH 4/4] 0.1.5.3 --- src/N_m3u8DL-RE/N_m3u8DL-RE.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/N_m3u8DL-RE/N_m3u8DL-RE.csproj b/src/N_m3u8DL-RE/N_m3u8DL-RE.csproj index e9274da3..c6ff558a 100644 --- a/src/N_m3u8DL-RE/N_m3u8DL-RE.csproj +++ b/src/N_m3u8DL-RE/N_m3u8DL-RE.csproj @@ -7,7 +7,7 @@ enable preview enable - 0.1.5.2 + 0.1.5.3 AnyCPU;x64