优化文件夹结构
This commit is contained in:
parent
1cc886a23e
commit
8945777e6b
|
@ -18,6 +18,8 @@ namespace N_m3u8DL_RE.Parser
|
|||
private string rawText;
|
||||
private static SemaphoreSlim semaphore = new SemaphoreSlim(1, 1);
|
||||
|
||||
public Dictionary<string, string> RawFiles { get; set; } = new(); //存储(文件名,文件内容)
|
||||
|
||||
public StreamExtractor()
|
||||
{
|
||||
|
||||
|
@ -55,24 +57,28 @@ namespace N_m3u8DL_RE.Parser
|
|||
|
||||
public void LoadSourceFromText(string rawText)
|
||||
{
|
||||
var rawType = "txt";
|
||||
rawText = rawText.Trim();
|
||||
this.rawText = rawText;
|
||||
if (rawText.StartsWith(HLSTags.ext_m3u))
|
||||
{
|
||||
Logger.InfoMarkUp(ResString.matchHLS);
|
||||
extractor = new HLSExtractor(parserConfig);
|
||||
rawType = "m3u8";
|
||||
}
|
||||
else if (rawText.Contains("</MPD>") && rawText.Contains("<MPD"))
|
||||
{
|
||||
Logger.InfoMarkUp(ResString.matchDASH);
|
||||
//extractor = new DASHExtractor(parserConfig);
|
||||
extractor = new DASHExtractor2(parserConfig);
|
||||
rawType = "mpd";
|
||||
}
|
||||
else if (rawText.Contains("</SmoothStreamingMedia>") && rawText.Contains("<SmoothStreamingMedia"))
|
||||
{
|
||||
Logger.InfoMarkUp(ResString.matchMSS);
|
||||
//extractor = new DASHExtractor(parserConfig);
|
||||
extractor = new MSSExtractor(parserConfig);
|
||||
rawType = "ism";
|
||||
}
|
||||
else if (rawText == ResString.ReLiveTs)
|
||||
{
|
||||
|
@ -83,6 +89,8 @@ namespace N_m3u8DL_RE.Parser
|
|||
{
|
||||
throw new NotSupportedException(ResString.notSupported);
|
||||
}
|
||||
|
||||
RawFiles[$"raw.{rawType}"] = rawText;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace N_m3u8DL_RE.CommandLine
|
|||
private readonly static Option<bool> DelAfterDone = new(new string[] { "--del-after-done" }, description: ResString.cmd_delAfterDone, getDefaultValue: () => true);
|
||||
private readonly static Option<bool> AutoSubtitleFix = new(new string[] { "--auto-subtitle-fix" }, description: ResString.cmd_subtitleFix, getDefaultValue: () => true);
|
||||
private readonly static Option<bool> CheckSegmentsCount = new(new string[] { "--check-segments-count" }, description: ResString.cmd_checkSegmentsCount, getDefaultValue: () => true);
|
||||
private readonly static Option<bool> WriteMetaJson = new(new string[] { "--write-meta-json" }, description: ResString.cmd_writeMetaJson, getDefaultValue: () => false);
|
||||
private readonly static Option<bool> WriteMetaJson = new(new string[] { "--write-meta-json" }, description: ResString.cmd_writeMetaJson, getDefaultValue: () => true);
|
||||
private readonly static Option<bool> AppendUrlParams = new(new string[] { "--append-url-params" }, description: ResString.cmd_appendUrlParams, getDefaultValue: () => false);
|
||||
private readonly static Option<bool> MP4RealTimeDecryption = new (new string[] { "--mp4-real-time-decryption" }, description: ResString.cmd_MP4RealTimeDecryption, getDefaultValue: () => false);
|
||||
private readonly static Option<bool> UseShakaPackager = new (new string[] { "--use-shaka-packager" }, description: ResString.cmd_useShakaPackager, getDefaultValue: () => false);
|
||||
|
|
|
@ -13,6 +13,10 @@ namespace N_m3u8DL_RE.Config
|
|||
{
|
||||
public required MyOption MyOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 前置阶段生成的文件夹名
|
||||
/// </summary>
|
||||
public required string DirPrefix { get; set; }
|
||||
/// <summary>
|
||||
/// 文件名模板
|
||||
/// </summary>
|
||||
|
|
|
@ -22,7 +22,6 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
DownloaderConfig DownloaderConfig;
|
||||
StreamExtractor StreamExtractor;
|
||||
List<StreamSpec> SelectedSteams;
|
||||
DateTime NowDateTime;
|
||||
List<OutputFile> OutputFiles = new();
|
||||
|
||||
public SimpleDownloadManager(DownloaderConfig downloaderConfig, List<StreamSpec> selectedSteams, StreamExtractor streamExtractor)
|
||||
|
@ -31,7 +30,6 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
this.SelectedSteams = selectedSteams;
|
||||
this.StreamExtractor = streamExtractor;
|
||||
Downloader = new SimpleDownloader(DownloaderConfig);
|
||||
NowDateTime = DateTime.Now;
|
||||
}
|
||||
|
||||
private string? ReadInit(byte[] data)
|
||||
|
@ -116,8 +114,8 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
}
|
||||
|
||||
var type = streamSpec.MediaType ?? Common.Enum.MediaType.VIDEO;
|
||||
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 dirName = $"{task.Id}_{OtherUtil.GetValidFileName(streamSpec.GroupId ?? "", "-")}_{streamSpec.Codecs}_{streamSpec.Bandwidth}_{streamSpec.Language}";
|
||||
var tmpDir = Path.Combine(DownloaderConfig.DirPrefix, dirName);
|
||||
var saveDir = DownloaderConfig.MyOptions.SaveDir ?? Environment.CurrentDirectory;
|
||||
var saveName = DownloaderConfig.MyOptions.SaveName != null ? $"{DownloaderConfig.MyOptions.SaveName}.{streamSpec.Language}".TrimEnd('.') : dirName;
|
||||
var headers = DownloaderConfig.Headers;
|
||||
|
@ -670,6 +668,17 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
|
||||
var success = Results.Values.All(v => v == true);
|
||||
|
||||
//删除临时文件夹
|
||||
if (!DownloaderConfig.MyOptions.SkipMerge && DownloaderConfig.MyOptions.DelAfterDone && success)
|
||||
{
|
||||
foreach (var item in StreamExtractor.RawFiles)
|
||||
{
|
||||
var file = Path.Combine(DownloaderConfig.DirPrefix, item.Key);
|
||||
if (File.Exists(file)) File.Delete(file);
|
||||
}
|
||||
OtherUtil.SafeDeleteDir(DownloaderConfig.DirPrefix);
|
||||
}
|
||||
|
||||
//混流
|
||||
if (success && DownloaderConfig.MyOptions.MuxAfterDone && OutputFiles.Count > 0)
|
||||
{
|
||||
|
@ -681,7 +690,7 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
OutputFiles.ForEach(f => Logger.WarnMarkUp($"[grey]{Path.GetFileName(f.FilePath).EscapeMarkup()}[/]"));
|
||||
var saveDir = DownloaderConfig.MyOptions.SaveDir ?? Environment.CurrentDirectory;
|
||||
var ext = DownloaderConfig.MyOptions.MuxToMp4 ? ".mp4" : ".mkv";
|
||||
var outName = $"{DownloaderConfig.MyOptions.SaveName ?? NowDateTime.ToString("yyyy-MM-dd_HH-mm-ss")}.MUX";
|
||||
var outName = $"{DownloaderConfig.DirPrefix}.MUX";
|
||||
var outPath = Path.Combine(saveDir, outName);
|
||||
Logger.WarnMarkUp($"Muxing to [grey]{outName.EscapeMarkup()}{ext}[/]");
|
||||
var result = false;
|
||||
|
|
|
@ -33,7 +33,6 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
List<StreamSpec> SelectedSteams;
|
||||
ConcurrentDictionary<int, string> PipeSteamNamesDic = new();
|
||||
List<OutputFile> OutputFiles = new();
|
||||
DateTime NowDateTime;
|
||||
DateTime? PublishDateTime;
|
||||
bool STOP_FLAG = false;
|
||||
int WAIT_SEC = 0; //刷新间隔
|
||||
|
@ -52,7 +51,6 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
{
|
||||
this.DownloaderConfig = downloaderConfig;
|
||||
Downloader = new SimpleDownloader(DownloaderConfig);
|
||||
NowDateTime = DateTime.Now;
|
||||
PublishDateTime = selectedSteams.FirstOrDefault()?.PublishTime;
|
||||
StreamExtractor = streamExtractor;
|
||||
SelectedSteams = selectedSteams;
|
||||
|
@ -184,8 +182,8 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
|
||||
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}_{OtherUtil.GetValidFileName(streamSpec.GroupId ?? "", "-")}_{streamSpec.Codecs}_{streamSpec.Bandwidth}_{streamSpec.Language}";
|
||||
var tmpDir = Path.Combine(DownloaderConfig.MyOptions.TmpDir ?? Environment.CurrentDirectory, dirName);
|
||||
var dirName = $"{task.Id}_{OtherUtil.GetValidFileName(streamSpec.GroupId ?? "", "-")}_{streamSpec.Codecs}_{streamSpec.Bandwidth}_{streamSpec.Language}";
|
||||
var tmpDir = Path.Combine(DownloaderConfig.DirPrefix, dirName);
|
||||
var saveDir = DownloaderConfig.MyOptions.SaveDir ?? Environment.CurrentDirectory;
|
||||
var saveName = DownloaderConfig.MyOptions.SaveName != null ? $"{DownloaderConfig.MyOptions.SaveName}.{streamSpec.Language}".TrimEnd('.') : dirName;
|
||||
var headers = DownloaderConfig.Headers;
|
||||
|
@ -860,6 +858,17 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
|
||||
var success = Results.Values.All(v => v == true);
|
||||
|
||||
//删除临时文件夹
|
||||
if (!DownloaderConfig.MyOptions.SkipMerge && DownloaderConfig.MyOptions.DelAfterDone && success)
|
||||
{
|
||||
foreach (var item in StreamExtractor.RawFiles)
|
||||
{
|
||||
var file = Path.Combine(DownloaderConfig.DirPrefix, item.Key);
|
||||
if (File.Exists(file)) File.Delete(file);
|
||||
}
|
||||
OtherUtil.SafeDeleteDir(DownloaderConfig.DirPrefix);
|
||||
}
|
||||
|
||||
//混流
|
||||
if (success && DownloaderConfig.MyOptions.MuxAfterDone && OutputFiles.Count > 0)
|
||||
{
|
||||
|
@ -871,7 +880,7 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
OutputFiles.ForEach(f => Logger.WarnMarkUp($"[grey]{Path.GetFileName(f.FilePath).EscapeMarkup()}[/]"));
|
||||
var saveDir = DownloaderConfig.MyOptions.SaveDir ?? Environment.CurrentDirectory;
|
||||
var ext = DownloaderConfig.MyOptions.MuxToMp4 ? ".mp4" : ".mkv";
|
||||
var outName = $"{DownloaderConfig.MyOptions.SaveName ?? NowDateTime.ToString("yyyy-MM-dd_HH-mm-ss")}.MUX";
|
||||
var outName = $"{DownloaderConfig.DirPrefix}.MUX";
|
||||
var outPath = Path.Combine(saveDir, outName);
|
||||
Logger.WarnMarkUp($"Muxing to [grey]{outName.EscapeMarkup()}{ext}[/]");
|
||||
var result = false;
|
||||
|
|
|
@ -104,6 +104,8 @@ namespace N_m3u8DL_RE
|
|||
throw new FileNotFoundException(ResString.ffmpegNotFound);
|
||||
}
|
||||
|
||||
Logger.Extra($"ffmpeg: {option.FFmpegBinaryPath}");
|
||||
|
||||
//预先检查mkvmerge
|
||||
if (option.UseMkvmerge && option.MuxAfterDone)
|
||||
{
|
||||
|
@ -113,6 +115,7 @@ namespace N_m3u8DL_RE
|
|||
{
|
||||
throw new FileNotFoundException("mkvmerge not found");
|
||||
}
|
||||
Logger.Extra($"mkvmerge: {option.MkvmergeBinaryPath}");
|
||||
}
|
||||
|
||||
//预先检查
|
||||
|
@ -128,12 +131,14 @@ namespace N_m3u8DL_RE
|
|||
var file4 = GlobalUtil.FindExecutable("packager-win-x64");
|
||||
if (file == null && file2 == null && file3 == null && file4 == null) throw new FileNotFoundException("shaka-packager not found!");
|
||||
option.DecryptionBinaryPath = file ?? file2 ?? file3 ?? file4;
|
||||
Logger.Extra($"shaka-packager: {option.DecryptionBinaryPath}");
|
||||
}
|
||||
else
|
||||
{
|
||||
var file = GlobalUtil.FindExecutable("mp4decrypt");
|
||||
if (file == null) throw new FileNotFoundException("mp4decrypt not found!");
|
||||
option.DecryptionBinaryPath = file;
|
||||
Logger.Extra($"mp4decrypt: {option.DecryptionBinaryPath}");
|
||||
}
|
||||
}
|
||||
else if (!File.Exists(option.DecryptionBinaryPath))
|
||||
|
@ -191,6 +196,7 @@ namespace N_m3u8DL_RE
|
|||
//解析流信息
|
||||
var streams = await extractor.ExtractStreamsAsync();
|
||||
|
||||
|
||||
//全部媒体
|
||||
var lists = streams.OrderBy(p => p.MediaType).ThenByDescending(p => p.Bandwidth).ThenByDescending(GetOrder);
|
||||
//基本流
|
||||
|
@ -200,11 +206,12 @@ namespace N_m3u8DL_RE
|
|||
//可选字幕轨道
|
||||
var subs = lists.Where(x => x.MediaType == MediaType.SUBTITLES);
|
||||
|
||||
if (option.WriteMetaJson)
|
||||
{
|
||||
Logger.Warn(ResString.writeJson);
|
||||
await File.WriteAllTextAsync("meta.json", GlobalUtil.ConvertToJson(lists), Encoding.UTF8);
|
||||
}
|
||||
//生成文件夹
|
||||
var tmpDir = Path.Combine(option.TmpDir ?? Environment.CurrentDirectory, $"{option.SaveName ?? DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss")}");
|
||||
//记录文件
|
||||
extractor.RawFiles["meta.json"] = GlobalUtil.ConvertToJson(lists);
|
||||
//写出文件
|
||||
await WriteRawFilesAsync(option, extractor, tmpDir);
|
||||
|
||||
Logger.Info(ResString.streamsInfo, lists.Count(), basicStreams.Count(), audios.Count(), subs.Count());
|
||||
|
||||
|
@ -272,11 +279,9 @@ namespace N_m3u8DL_RE
|
|||
option.BinaryMerge = true;
|
||||
}
|
||||
|
||||
if (option.WriteMetaJson)
|
||||
{
|
||||
Logger.Warn(ResString.writeJson);
|
||||
await File.WriteAllTextAsync("meta_selected.json", GlobalUtil.ConvertToJson(selectedStreams), Encoding.UTF8);
|
||||
}
|
||||
//记录文件
|
||||
extractor.RawFiles["meta_selected.json"] = GlobalUtil.ConvertToJson(selectedStreams);
|
||||
|
||||
|
||||
Logger.Info(ResString.selectedStream);
|
||||
foreach (var item in selectedStreams)
|
||||
|
@ -284,12 +289,16 @@ namespace N_m3u8DL_RE
|
|||
Logger.InfoMarkUp(item.ToString());
|
||||
}
|
||||
|
||||
//写出文件
|
||||
await WriteRawFilesAsync(option, extractor, tmpDir);
|
||||
|
||||
if (option.SkipDownload)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
Console.WriteLine("Press any key to continue...");
|
||||
Console.ReadKey();
|
||||
#endif
|
||||
|
||||
|
@ -305,6 +314,7 @@ namespace N_m3u8DL_RE
|
|||
var downloadConfig = new DownloaderConfig()
|
||||
{
|
||||
MyOptions = option,
|
||||
DirPrefix = tmpDir,
|
||||
Headers = parserConfig.Headers, //使用命令行解析得到的Headers
|
||||
};
|
||||
|
||||
|
@ -338,6 +348,21 @@ namespace N_m3u8DL_RE
|
|||
}
|
||||
}
|
||||
|
||||
private static async Task WriteRawFilesAsync(MyOption option, StreamExtractor extractor, string tmpDir)
|
||||
{
|
||||
//写出json文件
|
||||
if (option.WriteMetaJson)
|
||||
{
|
||||
if (!Directory.Exists(tmpDir)) Directory.CreateDirectory(tmpDir);
|
||||
Logger.Warn(ResString.writeJson);
|
||||
foreach (var item in extractor.RawFiles)
|
||||
{
|
||||
var file = Path.Combine(tmpDir, item.Key);
|
||||
if (!File.Exists(file)) await File.WriteAllTextAsync(file, item.Value, Encoding.UTF8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static async Task CheckUpdateAsync()
|
||||
{
|
||||
try
|
||||
|
|
Loading…
Reference in New Issue