diff --git a/src/N_m3u8DL-RE.Common/Log/Logger.cs b/src/N_m3u8DL-RE.Common/Log/Logger.cs
index f6422ab..c7d88c7 100644
--- a/src/N_m3u8DL-RE.Common/Log/Logger.cs
+++ b/src/N_m3u8DL-RE.Common/Log/Logger.cs
@@ -22,7 +22,7 @@ public static partial class Logger
///
/// 本次运行日志文件所在位置
///
- private static string? LogFilePath { get; set; }
+ public static string? LogFilePath { get; set; }
// 读写锁
static ReaderWriterLockSlim LogWriteLock = new ReaderWriterLockSlim();
@@ -33,26 +33,30 @@ public static partial class Logger
try
{
- var logDir = Path.GetDirectoryName(Environment.ProcessPath) + "/Logs";
+ var logDir = Path.GetDirectoryName(LogFilePath) ?? (Path.GetDirectoryName(Environment.ProcessPath) + "/Logs");
if (!Directory.Exists(logDir))
{
Directory.CreateDirectory(logDir);
}
var now = DateTime.Now;
- LogFilePath = Path.Combine(logDir, now.ToString("yyyy-MM-dd_HH-mm-ss-fff") + ".log");
- int index = 1;
- var fileName = Path.GetFileNameWithoutExtension(LogFilePath);
+ if (string.IsNullOrEmpty(LogFilePath))
+ {
+ LogFilePath = Path.Combine(logDir, now.ToString("yyyy-MM-dd_HH-mm-ss-fff") + ".log");
+ int index = 1;
+ var fileName = Path.GetFileNameWithoutExtension(LogFilePath);
+ // 若文件存在则加序号
+ while (File.Exists(LogFilePath))
+ {
+ LogFilePath = Path.Combine(Path.GetDirectoryName(LogFilePath)!, $"{fileName}-{index++}.log");
+ }
+ }
+
string init = "LOG " + now.ToString("yyyy/MM/dd") + Environment.NewLine
+ "Save Path: " + Path.GetDirectoryName(LogFilePath) + Environment.NewLine
+ "Task Start: " + now.ToString("yyyy/MM/dd HH:mm:ss") + Environment.NewLine
+ "Task CommandLine: " + Environment.CommandLine;
init += $"{Environment.NewLine}{Environment.NewLine}";
- // 若文件存在则加序号
- while (File.Exists(LogFilePath))
- {
- LogFilePath = Path.Combine(Path.GetDirectoryName(LogFilePath)!, $"{fileName}-{index++}.log");
- }
File.WriteAllText(LogFilePath, init, Encoding.UTF8);
}
catch (Exception ex)
@@ -223,4 +227,4 @@ public static partial class Logger
LogWriteLock.ExitWriteLock();
}
}
-}
\ No newline at end of file
+}
diff --git a/src/N_m3u8DL-RE.Common/Resource/ResString.cs b/src/N_m3u8DL-RE.Common/Resource/ResString.cs
index 39983ae..f959958 100644
--- a/src/N_m3u8DL-RE.Common/Resource/ResString.cs
+++ b/src/N_m3u8DL-RE.Common/Resource/ResString.cs
@@ -62,6 +62,7 @@ public static class ResString
public static string cmd_saveDir => GetText("cmd_saveDir");
public static string cmd_saveName => GetText("cmd_saveName");
public static string cmd_savePattern => GetText("cmd_savePattern");
+ public static string cmd_logFilePath => GetText("cmd_logFilePath");
public static string cmd_skipDownload => GetText("cmd_skipDownload");
public static string cmd_noDateInfo => GetText("cmd_noDateInfo");
public static string cmd_noLog => GetText("cmd_noLog");
@@ -147,4 +148,4 @@ public static class ResString
return textObj.ZH_CN;
return CurrentLoc.StartsWith("zh-") ? textObj.ZH_TW : textObj.EN_US;
}
-}
\ No newline at end of file
+}
diff --git a/src/N_m3u8DL-RE.Common/Resource/StaticText.cs b/src/N_m3u8DL-RE.Common/Resource/StaticText.cs
index 7b3c259..ccc6281 100644
--- a/src/N_m3u8DL-RE.Common/Resource/StaticText.cs
+++ b/src/N_m3u8DL-RE.Common/Resource/StaticText.cs
@@ -310,6 +310,12 @@ internal static class StaticText
zhTW: "",
enUS: ""
),
+ ["cmd_logFilePath"] = new TextContainer
+ (
+ zhCN: "设置日志文件路径",
+ zhTW: "設定日誌檔案路徑",
+ enUS: "Set log file path"
+ ),
["cmd_skipDownload"] = new TextContainer
(
zhCN: "跳过下载",
@@ -966,4 +972,4 @@ internal static class StaticText
),
};
-}
\ No newline at end of file
+}
diff --git a/src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs b/src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs
index 010ef3e..c9e472e 100644
--- a/src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs
+++ b/src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs
@@ -31,6 +31,7 @@ internal static partial class CommandInvoker
private static readonly Option SaveDir = new(["--save-dir"], description: ResString.cmd_saveDir);
private static readonly Option SaveName = new(["--save-name"], description: ResString.cmd_saveName, parseArgument: ParseSaveName);
private static readonly Option SavePattern = new(["--save-pattern"], description: ResString.cmd_savePattern, getDefaultValue: () => "____");
+ private static readonly Option LogFilePath = new(["--log-file-path"], description: ResString.cmd_logFilePath, parseArgument: ParseFilePath);
private static readonly Option UILanguage = new Option(["--ui-language"], description: ResString.cmd_uiLanguage).FromAmong("en-US", "zh-CN", "zh-TW");
private static readonly Option UrlProcessorArgs = new(["--urlprocessor-args"], description: ResString.cmd_urlProcessorArgs);
private static readonly Option Keys = new(["--key"], description: ResString.cmd_keys) { Arity = ArgumentArity.OneOrMore, AllowMultipleArgumentsPerToken = false };
@@ -292,6 +293,20 @@ internal static partial class CommandInvoker
return newName;
}
+ private static string? ParseFilePath(ArgumentResult result)
+ {
+ var input = result.Tokens[0].Value;
+ var dir = Path.GetDirectoryName(input);
+ var filename = Path.GetFileName(input);
+ var newName = OtherUtil.GetValidFileName(filename);
+ if (string.IsNullOrEmpty(newName))
+ {
+ result.ErrorMessage = "Invalid log file name!";
+ return null;
+ }
+ return Path.Combine(dir!, newName);
+ }
+
///
/// 流过滤器
///
@@ -515,6 +530,7 @@ internal static partial class CommandInvoker
TmpDir = bindingContext.ParseResult.GetValueForOption(TmpDir),
SaveDir = bindingContext.ParseResult.GetValueForOption(SaveDir),
SaveName = bindingContext.ParseResult.GetValueForOption(SaveName),
+ LogFilePath = bindingContext.ParseResult.GetValueForOption(LogFilePath),
ThreadCount = bindingContext.ParseResult.GetValueForOption(ThreadCount),
UILanguage = bindingContext.ParseResult.GetValueForOption(UILanguage),
SkipDownload = bindingContext.ParseResult.GetValueForOption(SkipDownload),
@@ -613,7 +629,7 @@ internal static partial class CommandInvoker
var rootCommand = new RootCommand(VERSION_INFO)
{
- Input, TmpDir, SaveDir, SaveName, BaseUrl, ThreadCount, DownloadRetryCount, HttpRequestTimeout, ForceAnsiConsole, NoAnsiColor,AutoSelect, SkipMerge, SkipDownload, CheckSegmentsCount,
+ Input, TmpDir, SaveDir, SaveName, LogFilePath, BaseUrl, ThreadCount, DownloadRetryCount, HttpRequestTimeout, ForceAnsiConsole, NoAnsiColor,AutoSelect, SkipMerge, SkipDownload, CheckSegmentsCount,
BinaryMerge, UseFFmpegConcatDemuxer, DelAfterDone, NoDateInfo, NoLog, WriteMetaJson, AppendUrlParams, ConcurrentDownload, Headers, /**SavePattern,**/ SubOnly, SubtitleFormat, AutoSubtitleFix,
FFmpegBinaryPath,
LogLevel, UILanguage, UrlProcessorArgs, Keys, KeyTextFile, DecryptionEngine, DecryptionBinaryPath, UseShakaPackager, MP4RealTimeDecryption,
diff --git a/src/N_m3u8DL-RE/CommandLine/MyOption.cs b/src/N_m3u8DL-RE/CommandLine/MyOption.cs
index a3b78b8..198187b 100644
--- a/src/N_m3u8DL-RE/CommandLine/MyOption.cs
+++ b/src/N_m3u8DL-RE/CommandLine/MyOption.cs
@@ -190,6 +190,10 @@ internal class MyOption
///
public string? SavePattern { get; set; }
///
+ /// See: .
+ ///
+ public string? LogFilePath { get; set; }
+ ///
/// See: .
///
public string? UILanguage { get; set; }
@@ -271,4 +275,4 @@ internal class MyOption
/// See: .
///
public bool LiveFixVttByAudio { get; set; }
-}
\ No newline at end of file
+}
diff --git a/src/N_m3u8DL-RE/Program.cs b/src/N_m3u8DL-RE/Program.cs
index f773cad..a945046 100644
--- a/src/N_m3u8DL-RE/Program.cs
+++ b/src/N_m3u8DL-RE/Program.cs
@@ -101,6 +101,7 @@ internal class Program
_ = CheckUpdateAsync();
Logger.IsWriteFile = !option.NoLog;
+ Logger.LogFilePath = option.LogFilePath;
Logger.InitLogFile();
Logger.LogLevel = option.LogLevel;
Logger.Info(CommandInvoker.VERSION_INFO);
@@ -479,4 +480,4 @@ internal class Program
return redirectedUrl;
}
-}
\ No newline at end of file
+}