diff --git a/src/N_m3u8DL-RE.Common/Resource/ResString.cs b/src/N_m3u8DL-RE.Common/Resource/ResString.cs index 9078216..4dd6535 100644 --- a/src/N_m3u8DL-RE.Common/Resource/ResString.cs +++ b/src/N_m3u8DL-RE.Common/Resource/ResString.cs @@ -71,6 +71,7 @@ namespace N_m3u8DL_RE.Common.Resource public static string cmd_muxAfterDone_more { get => GetText("cmd_muxAfterDone_more"); } public static string cmd_writeMetaJson { get => GetText("cmd_writeMetaJson"); } public static string liveLimit { get => GetText("liveLimit"); } + public static string realTimeDecMessage { get => GetText("realTimeDecMessage"); } public static string liveLimitReached { get => GetText("liveLimitReached"); } public static string saveName { get => GetText("saveName"); } public static string partMerge { get => GetText("partMerge"); } diff --git a/src/N_m3u8DL-RE.Common/Resource/StaticText.cs b/src/N_m3u8DL-RE.Common/Resource/StaticText.cs index 36b59f8..61f561c 100644 --- a/src/N_m3u8DL-RE.Common/Resource/StaticText.cs +++ b/src/N_m3u8DL-RE.Common/Resource/StaticText.cs @@ -499,6 +499,12 @@ namespace N_m3u8DL_RE.Common.Resource zhTW: "本次直播錄製時長上限: ", enUS: "Live recording duration limit: " ), + ["realTimeDecMessage"] = new TextContainer + ( + zhCN: "启用实时解密时,建议用shaka-packager而非mp4decrypt", + zhTW: "啟用即時解密時,建議用shaka-packager而非mp4decrypt", + enUS: "When enabling real-time decryption, it is recommended to use shaka-packager instead of mp4decrypt" + ), ["liveLimitReached"] = new TextContainer ( zhCN: "到达直播录制上限,即将停止录制", diff --git a/src/N_m3u8DL-RE.Parser/Extractor/HLSExtractor.cs b/src/N_m3u8DL-RE.Parser/Extractor/HLSExtractor.cs index 97b8f53..f21f46d 100644 --- a/src/N_m3u8DL-RE.Parser/Extractor/HLSExtractor.cs +++ b/src/N_m3u8DL-RE.Parser/Extractor/HLSExtractor.cs @@ -525,7 +525,7 @@ namespace N_m3u8DL_RE.Parser.Extractor } } } - else if (lists.Count == 1 && ParserConfig.OriginalUrl != lists[0].Url) + else if (!MasterM3u8Flag && lists.Count == 1 && ParserConfig.OriginalUrl != lists[0].Url) { //单m3u8, 但是发生了重定向, 则应从原始URL开始解析 lists[0].Url = ParserConfig.OriginalUrl; diff --git a/src/N_m3u8DL-RE/DownloadManager/SimpleDownloadManager.cs b/src/N_m3u8DL-RE/DownloadManager/SimpleDownloadManager.cs index 7d2d069..8d34d9f 100644 --- a/src/N_m3u8DL-RE/DownloadManager/SimpleDownloadManager.cs +++ b/src/N_m3u8DL-RE/DownloadManager/SimpleDownloadManager.cs @@ -589,6 +589,10 @@ namespace N_m3u8DL_RE.DownloadManager new SpinnerColumn(), }); + if (DownloaderConfig.MyOptions.MP4RealTimeDecryption && !DownloaderConfig.MyOptions.UseShakaPackager + && DownloaderConfig.MyOptions.Keys != null && DownloaderConfig.MyOptions.Keys.Length > 0) + Logger.WarnMarkUp($"[darkorange3_1]{ResString.realTimeDecMessage}[/]"); + await progress.StartAsync(async ctx => { //创建任务 diff --git a/src/N_m3u8DL-RE/DownloadManager/SimpleLiveRecordManager2.cs b/src/N_m3u8DL-RE/DownloadManager/SimpleLiveRecordManager2.cs index 1bdd8ea..8ff7360 100644 --- a/src/N_m3u8DL-RE/DownloadManager/SimpleLiveRecordManager2.cs +++ b/src/N_m3u8DL-RE/DownloadManager/SimpleLiveRecordManager2.cs @@ -29,7 +29,7 @@ namespace N_m3u8DL_RE.DownloadManager bool STOP_FLAG = false; int WAIT_SEC = 0; //刷新间隔 ConcurrentDictionary RecordingDurDic = new(); //已录制时长 - ConcurrentDictionary LastUrlDic = new(); //上次下载的url + ConcurrentDictionary LastFileNameDic = new(); //上次下载的文件名 ConcurrentDictionary DateTimeDic = new(); //上次下载的dateTime CancellationTokenSource CancellationTokenSource = new(); //取消Wait @@ -178,6 +178,7 @@ namespace N_m3u8DL_RE.DownloadManager //TryReceiveAll可以稍微缓解一下 source.TryReceiveAll(out IList>? segmentsList); var segments = segmentsList!.SelectMany(s => s); + Logger.DebugMarkUp(string.Join(",", segments.Select(sss => GetSegmentName(sss, false)))); //下载init if (!initDownloaded && streamSpec.Playlist?.MediaInit != null) @@ -529,15 +530,16 @@ namespace N_m3u8DL_RE.DownloadManager { if (WAIT_SEC != 0) { + var allHasDatetime = streamSpec.Playlist!.MediaParts[0].MediaSegments.All(s => s.DateTime != null); //过滤不需要下载的片段 - FilterMediaSegments(streamSpec, LastUrlDic[streamSpec.ToShortString()], DateTimeDic[streamSpec.ToShortString()]); + FilterMediaSegments(streamSpec, allHasDatetime); var newList = streamSpec.Playlist!.MediaParts[0].MediaSegments; if (newList.Count > 0) { //推送给消费者 await target.SendAsync(newList); //更新最新链接 - LastUrlDic[streamSpec.ToShortString()] = GetPath(newList.Last().Url); + LastFileNameDic[streamSpec.ToShortString()] = GetSegmentName(newList.Last(), allHasDatetime); //尝试更新时间戳 var dt = newList.Last().DateTime; DateTimeDic[streamSpec.ToShortString()] = dt != null ? GetUnixTimestamp(dt.Value) : 0L; @@ -560,11 +562,13 @@ namespace N_m3u8DL_RE.DownloadManager target.Complete(); } - private void FilterMediaSegments(StreamSpec streamSpec, string lastUrl, long dateTime) + private void FilterMediaSegments(StreamSpec streamSpec, bool allHasDatetime) { - if (string.IsNullOrEmpty(lastUrl) && dateTime == 0) return; + if (string.IsNullOrEmpty(LastFileNameDic[streamSpec.ToShortString()]) && DateTimeDic[streamSpec.ToShortString()] == 0) return; var index = -1; + var dateTime = DateTimeDic[streamSpec.ToShortString()]; + var lastName = LastFileNameDic[streamSpec.ToShortString()]; //优先使用dateTime判断 if (dateTime != 0 && streamSpec.Playlist!.MediaParts[0].MediaSegments.All(s => s.DateTime != null)) @@ -573,7 +577,7 @@ namespace N_m3u8DL_RE.DownloadManager } else { - index = streamSpec.Playlist!.MediaParts[0].MediaSegments.FindIndex(s => GetPath(s.Url) == lastUrl); + index = streamSpec.Playlist!.MediaParts[0].MediaSegments.FindIndex(s => GetSegmentName(s, allHasDatetime) == lastName); } if (index > -1) @@ -582,11 +586,6 @@ namespace N_m3u8DL_RE.DownloadManager } } - private string GetPath(string url) - { - return url.Split('?').First(); - } - public async Task StartRecordAsync() { var takeLastCount = 15; @@ -604,7 +603,7 @@ namespace N_m3u8DL_RE.DownloadManager //初始化dic foreach (var item in SelectedSteams) { - LastUrlDic[item.ToShortString()] = ""; + LastFileNameDic[item.ToShortString()] = ""; DateTimeDic[item.ToShortString()] = 0L; } //设置等待时间 @@ -645,6 +644,9 @@ namespace N_m3u8DL_RE.DownloadManager DownloaderConfig.MyOptions.ConcurrentDownload = true; DownloaderConfig.MyOptions.MP4RealTimeDecryption = true; DownloaderConfig.MyOptions.LiveRecordLimit = DownloaderConfig.MyOptions.LiveRecordLimit ?? TimeSpan.MaxValue; + if (DownloaderConfig.MyOptions.MP4RealTimeDecryption && !DownloaderConfig.MyOptions.UseShakaPackager + && DownloaderConfig.MyOptions.Keys != null && DownloaderConfig.MyOptions.Keys.Length > 0) + Logger.WarnMarkUp($"[darkorange3_1]{ResString.realTimeDecMessage}[/]"); var limit = DownloaderConfig.MyOptions.LiveRecordLimit; if (limit != TimeSpan.MaxValue) Logger.WarnMarkUp($"[darkorange3_1]{ResString.liveLimit}{GlobalUtil.FormatTime((int)limit.Value.TotalSeconds)}[/]"); diff --git a/src/N_m3u8DL-RE/N_m3u8DL-RE.csproj b/src/N_m3u8DL-RE/N_m3u8DL-RE.csproj index 760f796..4c9bc1b 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.0.4 + 0.0.5