优化文件夹结构

This commit is contained in:
nilaoda 2023-06-14 22:07:48 +08:00
parent 1cc886a23e
commit 8945777e6b
6 changed files with 79 additions and 24 deletions

View File

@ -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>

View File

@ -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);

View File

@ -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>

View File

@ -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;

View File

@ -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;

View File

@ -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
};
@ -315,7 +325,7 @@ namespace N_m3u8DL_RE
var sldm = new HTTPLiveRecordManager(downloadConfig, selectedStreams, extractor);
result = await sldm.StartRecordAsync();
}
else if(!livingFlag)
else if (!livingFlag)
{
//开始下载
var sdm = new SimpleDownloadManager(downloadConfig, selectedStreams, extractor);
@ -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