diff --git a/src/N_m3u8DL-RE.Common/Resource/ResString.cs b/src/N_m3u8DL-RE.Common/Resource/ResString.cs index 31eff18..39694da 100644 --- a/src/N_m3u8DL-RE.Common/Resource/ResString.cs +++ b/src/N_m3u8DL-RE.Common/Resource/ResString.cs @@ -72,6 +72,7 @@ namespace N_m3u8DL_RE.Common.Resource public static string liveLimit { get => GetText("liveLimit"); } public static string liveLimitReached { get => GetText("liveLimitReached"); } public static string saveName { get => GetText("saveName"); } + public static string partMerge { get => GetText("partMerge"); } public static string fetch { get => GetText("fetch"); } public static string ffmpegMerge { get => GetText("ffmpegMerge"); } public static string ffmpegNotFound { get => GetText("ffmpegNotFound"); } diff --git a/src/N_m3u8DL-RE.Common/Resource/StaticText.cs b/src/N_m3u8DL-RE.Common/Resource/StaticText.cs index dc89ce5..9b63a9d 100644 --- a/src/N_m3u8DL-RE.Common/Resource/StaticText.cs +++ b/src/N_m3u8DL-RE.Common/Resource/StaticText.cs @@ -583,6 +583,12 @@ namespace N_m3u8DL_RE.Common.Resource zhTW: "內容匹配: [white on deepskyblue1]HTTP Live Streaming[/]", enUS: "Content Matched: [white on deepskyblue1]HTTP Live Streaming[/]" ), + ["partMerge"] = new TextContainer + ( + zhCN: "分片数量大于1800个,开始分块合并...", + zhTW: "分片數量大於1800個,開始分塊合併...", + enUS: "Segments more than 1800, start partial merge..." + ), ["notSupported"] = new TextContainer ( zhCN: "当前输入不受支持: ", diff --git a/src/N_m3u8DL-RE/DownloadManager/SimpleDownloadManager.cs b/src/N_m3u8DL-RE/DownloadManager/SimpleDownloadManager.cs index aaf98ef..56f77ab 100644 --- a/src/N_m3u8DL-RE/DownloadManager/SimpleDownloadManager.cs +++ b/src/N_m3u8DL-RE/DownloadManager/SimpleDownloadManager.cs @@ -11,6 +11,7 @@ using N_m3u8DL_RE.Util; using Spectre.Console; using Spectre.Console.Rendering; using System.Collections.Concurrent; +using System.IO; using System.Text; namespace N_m3u8DL_RE.DownloadManager @@ -509,6 +510,20 @@ namespace N_m3u8DL_RE.DownloadManager { Logger.WarnMarkUp($"{Path.GetFileName(ffOut)} => {Path.GetFileName(ffOut = Path.ChangeExtension(ffOut, $"copy" + Path.GetExtension(ffOut)))}"); } + //大于1800分片,需要分步骤合并 + if (files.Length >= 1800) + { + Logger.WarnMarkUp(ResString.partMerge); + files = MergeUtil.PartialCombineMultipleFiles(files); + FileDic.Clear(); + foreach (var item in files) + { + FileDic[new MediaSegment() { Url = item }] = new DownloadResult() + { + ActualFilePath = item + }; + } + } mergeSuccess = MergeUtil.MergeByFFmpeg(DownloaderConfig.MyOptions.FFmpegBinaryPath!, files, Path.ChangeExtension(ffOut, null), ext, useAACFilter); if (mergeSuccess) output = ffOut; } diff --git a/src/N_m3u8DL-RE/Util/MergeUtil.cs b/src/N_m3u8DL-RE/Util/MergeUtil.cs index 849465d..ea90585 100644 --- a/src/N_m3u8DL-RE/Util/MergeUtil.cs +++ b/src/N_m3u8DL-RE/Util/MergeUtil.cs @@ -75,6 +75,38 @@ namespace N_m3u8DL_RE.Util p.WaitForExit(); } + public static string[] PartialCombineMultipleFiles(string[] files) + { + var newFiles = new List(); + int div = 0; + if (files.Length <= 90000) + div = 100; + else + div = 200; + + string outputName = Path.GetDirectoryName(files[0]) + "\\T"; + int index = 0; //序号 + + //按照div的容量分割为小数组 + string[][] li = Enumerable.Range(0, files.Count() / div + 1).Select(x => files.Skip(x * div).Take(div).ToArray()).ToArray(); + foreach (var items in li) + { + if (items.Count() == 0) + continue; + var output = outputName + index.ToString("0000") + ".ts"; + CombineMultipleFilesIntoSingleFile(items, output); + newFiles.Add(output); + //合并后删除这些文件 + foreach (var item in items) + { + File.Delete(item); + } + index++; + } + + return newFiles.ToArray(); + } + public static bool MergeByFFmpeg(string binary, string[] files, string outputPath, string muxFormat, bool useAACFilter, bool fastStart = false, bool writeDate = true, string poster = "", string audioName = "", string title = "",