diff --git a/src/N_m3u8DL-RE.Common/Resource/ResString.Designer.cs b/src/N_m3u8DL-RE.Common/Resource/ResString.Designer.cs
index 2370ebd..033d504 100644
--- a/src/N_m3u8DL-RE.Common/Resource/ResString.Designer.cs
+++ b/src/N_m3u8DL-RE.Common/Resource/ResString.Designer.cs
@@ -134,7 +134,7 @@ namespace N_m3u8DL_RE.Common.Resource {
///
/// 查找类似 Pass custom header(s) to server, Example:
- /// -H "Cookie: mycookie" -H "User-Agent: iOS" 的本地化字符串。
+ ///-H "Cookie: mycookie" -H "User-Agent: iOS" 的本地化字符串。
///
public static string cmd_header {
get {
@@ -151,6 +151,16 @@ namespace N_m3u8DL_RE.Common.Resource {
}
}
+ ///
+ /// 查找类似 Pass decryption key(s) to mp4decrypt. format:
+ ///--key KID1:KEY1 --key KID2:KEY2 的本地化字符串。
+ ///
+ public static string cmd_keys {
+ get {
+ return ResourceManager.GetString("cmd_keys", resourceCulture);
+ }
+ }
+
///
/// 查找类似 Set log level 的本地化字符串。
///
@@ -178,6 +188,15 @@ namespace N_m3u8DL_RE.Common.Resource {
}
}
+ ///
+ /// 查找类似 的本地化字符串。
+ ///
+ public static string cmd_savePattern {
+ get {
+ return ResourceManager.GetString("cmd_savePattern", resourceCulture);
+ }
+ }
+
///
/// 查找类似 Skip download 的本地化字符串。
///
diff --git a/src/N_m3u8DL-RE.Common/Resource/ResString.resx b/src/N_m3u8DL-RE.Common/Resource/ResString.resx
index ad6a70f..3706635 100644
--- a/src/N_m3u8DL-RE.Common/Resource/ResString.resx
+++ b/src/N_m3u8DL-RE.Common/Resource/ResString.resx
@@ -174,7 +174,7 @@
Pass custom header(s) to server, Example:
- -H "Cookie: mycookie" -H "User-Agent: iOS"
+-H "Cookie: mycookie" -H "User-Agent: iOS"
Set log level
@@ -227,4 +227,11 @@
Add Params of input Url to segments, useful for some websites, such as kakao.com
+
+
+
+
+ Pass decryption key(s) to mp4decrypt. format:
+--key KID1:KEY1 --key KID2:KEY2
+
\ No newline at end of file
diff --git a/src/N_m3u8DL-RE.Common/Resource/ResString.zh-Hans.resx b/src/N_m3u8DL-RE.Common/Resource/ResString.zh-Hans.resx
index d278da2..651e5c2 100644
--- a/src/N_m3u8DL-RE.Common/Resource/ResString.zh-Hans.resx
+++ b/src/N_m3u8DL-RE.Common/Resource/ResString.zh-Hans.resx
@@ -194,7 +194,7 @@
为HTTP请求设置特定的请求头, 例如:
- -H "Cookie: mycookie" -H "User-Agent: iOS"
+-H "Cookie: mycookie" -H "User-Agent: iOS"
设置日志级别
@@ -247,4 +247,11 @@
将输入Url的Params添加至分片, 对某些网站很有用, 例如 kakao.com
+
+ 设置保存文件命名模板, 支持使用变量
+
+
+ 设置解密密钥, 程序调用mp4decrpyt进行解密. 格式:
+--key KID1:KEY1 --key KID2:KEY2
+
\ No newline at end of file
diff --git a/src/N_m3u8DL-RE.Common/Resource/ResString.zh-Hant.resx b/src/N_m3u8DL-RE.Common/Resource/ResString.zh-Hant.resx
index d69c885..a38ffbe 100644
--- a/src/N_m3u8DL-RE.Common/Resource/ResString.zh-Hant.resx
+++ b/src/N_m3u8DL-RE.Common/Resource/ResString.zh-Hant.resx
@@ -174,7 +174,7 @@
為HTTP請求設置特定的請求頭, 例如:
- -H "Cookie: mycookie" -H "User-Agent: iOS"
+-H "Cookie: mycookie" -H "User-Agent: iOS"
設置日誌級別
@@ -227,4 +227,8 @@
將輸入Url的Params添加至分片, 對某些網站很有用, 例如 kakao.com
+
+ 設置解密密鑰, 程序調用mp4decrpyt進行解密. 格式:
+--key KID1:KEY1 --key KID2:KEY2
+
\ 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 6c89086..f59b5a3 100644
--- a/src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs
+++ b/src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs
@@ -14,7 +14,9 @@ namespace N_m3u8DL_RE.CommandLine
private readonly static Option TmpDir = new(new string[] { "--tmp-dir" }, description: ResString.cmd_tmpDir);
private readonly static Option SaveDir = new(new string[] { "--save-dir", "-o" }, description: ResString.cmd_saveDir);
private readonly static Option SaveName = new(new string[] { "--save-name", "-O" }, description: ResString.cmd_saveName);
+ private readonly static Option SavePattern = new(new string[] { "--save-pattern" }, description: ResString.cmd_savePattern, getDefaultValue: () => "____");
private readonly static Option UILanguage = new(new string[] { "--ui-language" }, description: ResString.cmd_uiLanguage);
+ private readonly static Option Keys = new(new string[] { "--key" }, description: ResString.cmd_keys) { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = false };
private readonly static Option Headers = new(new string[] { "--header", "-H" }, description: ResString.cmd_header) { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = false };
private readonly static Option LogLevel = new(name: "--log-level", description: ResString.cmd_logLevel, getDefaultValue: () => Common.Log.LogLevel.INFO);
private readonly static Option SubtitleFormat = new(name: "--sub-format", description: ResString.cmd_subFormat, getDefaultValue: () => Enum.SubtitleFormat.VTT);
@@ -55,6 +57,8 @@ namespace N_m3u8DL_RE.CommandLine
SkipDownload = bindingContext.ParseResult.GetValueForOption(SkipDownload),
WriteMetaJson = bindingContext.ParseResult.GetValueForOption(WriteMetaJson),
AppendUrlParams = bindingContext.ParseResult.GetValueForOption(AppendUrlParams),
+ SavePattern = bindingContext.ParseResult.GetValueForOption(SavePattern),
+ Keys = bindingContext.ParseResult.GetValueForOption(Keys),
};
//在这里设置语言
@@ -79,10 +83,10 @@ namespace N_m3u8DL_RE.CommandLine
public static async Task InvokeArgs(string[] args, Func action)
{
- var rootCommand = new RootCommand("N_m3u8DL-RE Beta version: 20220719")
+ var rootCommand = new RootCommand("N_m3u8DL-RE (Beta version) 20220721")
{
Input, TmpDir, SaveDir, SaveName, ThreadCount, AutoSelect, SkipMerge, SkipDownload, CheckSegmentsCount,
- BinaryMerge, DelAfterDone, WriteMetaJson, AppendUrlParams, Headers, SubOnly, SubtitleFormat, AutoSubtitleFix,
+ BinaryMerge, DelAfterDone, WriteMetaJson, AppendUrlParams, Keys, Headers, /**SavePattern,**/ SubOnly, SubtitleFormat, AutoSubtitleFix,
LogLevel, UILanguage
};
rootCommand.TreatUnmatchedTokensAsErrors = true;
diff --git a/src/N_m3u8DL-RE/CommandLine/MyOption.cs b/src/N_m3u8DL-RE/CommandLine/MyOption.cs
index 6a8abbb..1f6b248 100644
--- a/src/N_m3u8DL-RE/CommandLine/MyOption.cs
+++ b/src/N_m3u8DL-RE/CommandLine/MyOption.cs
@@ -14,6 +14,10 @@ namespace N_m3u8DL_RE.CommandLine
///
public string[]? Headers { get; set; }
///
+ /// See: .
+ ///
+ public string[]? Keys { get; set; }
+ ///
/// See: .
///
public LogLevel LogLevel { get; set; }
@@ -78,6 +82,10 @@ namespace N_m3u8DL_RE.CommandLine
///
public string? SaveName { get; set; }
///
+ /// See: .
+ ///
+ public string? SavePattern { get; set; }
+ ///
/// See: .
///
public string? UILanguage { get; set; }
diff --git a/src/N_m3u8DL-RE/Config/DownloaderConfig.cs b/src/N_m3u8DL-RE/Config/DownloaderConfig.cs
index 7b368f0..6541d79 100644
--- a/src/N_m3u8DL-RE/Config/DownloaderConfig.cs
+++ b/src/N_m3u8DL-RE/Config/DownloaderConfig.cs
@@ -25,6 +25,8 @@ namespace N_m3u8DL_RE.Config
SaveName = option.SaveName;
SaveDir = option.SaveDir;
ThreadCount = option.ThreadCount;
+ SavePattern = option.SavePattern;
+ Keys = option.Keys;
}
///
@@ -40,6 +42,10 @@ namespace N_m3u8DL_RE.Config
///
public string? SaveName { get; set; }
///
+ /// 文件名模板
+ ///
+ public string? SavePattern { get; set; }
+ ///
/// 线程数
///
public int ThreadCount { get; set; } = 8;
@@ -78,5 +84,9 @@ namespace N_m3u8DL_RE.Config
{
["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"
};
+ ///
+ /// 解密KEYs
+ ///
+ public string[]? Keys { get; set; }
}
}
diff --git a/src/N_m3u8DL-RE/DownloadManager/SimpleDownloadManager.cs b/src/N_m3u8DL-RE/DownloadManager/SimpleDownloadManager.cs
index efa80a9..390cb2f 100644
--- a/src/N_m3u8DL-RE/DownloadManager/SimpleDownloadManager.cs
+++ b/src/N_m3u8DL-RE/DownloadManager/SimpleDownloadManager.cs
@@ -313,7 +313,7 @@ namespace N_m3u8DL_RE.DownloadManager
}
}
- if (DownloaderConfig.Keys != null)
+ if (DownloaderConfig.Keys != null && DownloaderConfig.Keys.Length > 0)
{
var APP_DIR = Path.GetDirectoryName(Environment.ProcessPath)!;
var fileName = "mp4decrypt";
@@ -325,7 +325,7 @@ namespace N_m3u8DL_RE.DownloadManager
&& streamSpec.Playlist!.MediaParts.First().MediaSegments.First().EncryptInfo.Method != Common.Enum.EncryptMethod.NONE)
{
var enc = output;
- var dec = Path.Combine(Path.GetDirectoryName(enc)!, Path.GetFileNameWithoutExtension(enc) + "_dec.mp4");
+ var dec = Path.Combine(Path.GetDirectoryName(enc)!, Path.GetFileNameWithoutExtension(enc) + "_dec" + Path.GetExtension(enc));
var cmd = string.Join(" ", DownloaderConfig.Keys.Select(k => $"--key {k}")) + $" \"{enc}\" \"{dec}\"";
Logger.InfoMarkUp($"[grey]Decrypting...[/]");
await Process.Start(new ProcessStartInfo()
diff --git a/src/N_m3u8DL-RE/Program.cs b/src/N_m3u8DL-RE/Program.cs
index 4a5dfba..9cb2c51 100644
--- a/src/N_m3u8DL-RE/Program.cs
+++ b/src/N_m3u8DL-RE/Program.cs
@@ -77,6 +77,7 @@ namespace N_m3u8DL_RE
//url = "https://dcs-vod.mp.lura.live/vod/p/session/manifest.mpd?i=i177610817-nb45239a2-e962-4137-bc70-1790359619e6";
//url = "https://theater.kktv.com.tw/98/04000198010001_584b26392f7f7f11fc62299214a55fb7/16113081449d8d5e9960_sub_dash.mpd"; //MPD+VTT
//url = "https://vsl.play.kakao.com/vod/rvty90n7btua6u9oebr97i8zl/dash/vhs/cenc/adaptive.mpd?e=1658297362&p=71&h=53766bdde112d59da2b2514e8ab41e81"; //需要补params
+ //url = "https://a38avoddashs3ww-a.akamaihd.net/ondemand/iad_2/8e91/f2f2/ec5a/430f-bd7a-0779f4a0189d/685cda75-609c-41c1-86bb-688f4cdb5521_corrected.mpd";
//url = "";
if (!string.IsNullOrEmpty(option.Input))
@@ -96,6 +97,13 @@ namespace N_m3u8DL_RE
//解析流信息
var streams = await extractor.ExtractStreamsAsync();
+ //直播检测
+ var livingFlag = streams.Any(s => s.Playlist?.IsLive == true);
+ if (livingFlag)
+ {
+ Logger.WarnMarkUp($"[white on darkorange3_1]{ResString.liveFound}[/]");
+ }
+
//全部媒体
var lists = streams.OrderBy(p => p.MediaType).ThenByDescending(p => p.Bandwidth);
//基本流