增加`--key`选项

This commit is contained in:
nilaoda 2022-07-21 18:18:33 +08:00
parent 3ab04d2c5f
commit 91cab2c7e3
9 changed files with 75 additions and 8 deletions

View File

@ -151,6 +151,16 @@ namespace N_m3u8DL_RE.Common.Resource {
} }
} }
/// <summary>
/// 查找类似 Pass decryption key(s) to mp4decrypt. format:
///--key KID1:KEY1 --key KID2:KEY2 的本地化字符串。
/// </summary>
public static string cmd_keys {
get {
return ResourceManager.GetString("cmd_keys", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Set log level 的本地化字符串。 /// 查找类似 Set log level 的本地化字符串。
/// </summary> /// </summary>
@ -178,6 +188,15 @@ namespace N_m3u8DL_RE.Common.Resource {
} }
} }
/// <summary>
/// 查找类似 的本地化字符串。
/// </summary>
public static string cmd_savePattern {
get {
return ResourceManager.GetString("cmd_savePattern", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 Skip download 的本地化字符串。 /// 查找类似 Skip download 的本地化字符串。
/// </summary> /// </summary>

View File

@ -227,4 +227,11 @@
<data name="cmd_appendUrlParams" xml:space="preserve"> <data name="cmd_appendUrlParams" xml:space="preserve">
<value>Add Params of input Url to segments, useful for some websites, such as kakao.com</value> <value>Add Params of input Url to segments, useful for some websites, such as kakao.com</value>
</data> </data>
<data name="cmd_savePattern" xml:space="preserve">
<value></value>
</data>
<data name="cmd_keys" xml:space="preserve">
<value>Pass decryption key(s) to mp4decrypt. format:
--key KID1:KEY1 --key KID2:KEY2</value>
</data>
</root> </root>

View File

@ -247,4 +247,11 @@
<data name="cmd_appendUrlParams" xml:space="preserve"> <data name="cmd_appendUrlParams" xml:space="preserve">
<value>将输入Url的Params添加至分片, 对某些网站很有用, 例如 kakao.com</value> <value>将输入Url的Params添加至分片, 对某些网站很有用, 例如 kakao.com</value>
</data> </data>
<data name="cmd_savePattern" xml:space="preserve">
<value>设置保存文件命名模板, 支持使用变量</value>
</data>
<data name="cmd_keys" xml:space="preserve">
<value>设置解密密钥, 程序调用mp4decrpyt进行解密. 格式:
--key KID1:KEY1 --key KID2:KEY2</value>
</data>
</root> </root>

View File

@ -227,4 +227,8 @@
<data name="cmd_appendUrlParams" xml:space="preserve"> <data name="cmd_appendUrlParams" xml:space="preserve">
<value>將輸入Url的Params添加至分片, 對某些網站很有用, 例如 kakao.com</value> <value>將輸入Url的Params添加至分片, 對某些網站很有用, 例如 kakao.com</value>
</data> </data>
<data name="cmd_keys" xml:space="preserve">
<value>設置解密密鑰, 程序調用mp4decrpyt進行解密. 格式:
--key KID1:KEY1 --key KID2:KEY2</value>
</data>
</root> </root>

View File

@ -14,7 +14,9 @@ namespace N_m3u8DL_RE.CommandLine
private readonly static Option<string?> TmpDir = new(new string[] { "--tmp-dir" }, description: ResString.cmd_tmpDir); private readonly static Option<string?> TmpDir = new(new string[] { "--tmp-dir" }, description: ResString.cmd_tmpDir);
private readonly static Option<string?> SaveDir = new(new string[] { "--save-dir", "-o" }, description: ResString.cmd_saveDir); private readonly static Option<string?> SaveDir = new(new string[] { "--save-dir", "-o" }, description: ResString.cmd_saveDir);
private readonly static Option<string?> SaveName = new(new string[] { "--save-name", "-O" }, description: ResString.cmd_saveName); private readonly static Option<string?> SaveName = new(new string[] { "--save-name", "-O" }, description: ResString.cmd_saveName);
private readonly static Option<string?> SavePattern = new(new string[] { "--save-pattern" }, description: ResString.cmd_savePattern, getDefaultValue: () => "<SaveName>_<Id>_<Codecs>_<Language>_<Ext>");
private readonly static Option<string?> UILanguage = new(new string[] { "--ui-language" }, description: ResString.cmd_uiLanguage); private readonly static Option<string?> UILanguage = new(new string[] { "--ui-language" }, description: ResString.cmd_uiLanguage);
private readonly static Option<string[]?> Keys = new(new string[] { "--key" }, description: ResString.cmd_keys) { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = false };
private readonly static Option<string[]?> Headers = new(new string[] { "--header", "-H" }, description: ResString.cmd_header) { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = false }; private readonly static Option<string[]?> Headers = new(new string[] { "--header", "-H" }, description: ResString.cmd_header) { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = false };
private readonly static Option<LogLevel> LogLevel = new(name: "--log-level", description: ResString.cmd_logLevel, getDefaultValue: () => Common.Log.LogLevel.INFO); private readonly static Option<LogLevel> LogLevel = new(name: "--log-level", description: ResString.cmd_logLevel, getDefaultValue: () => Common.Log.LogLevel.INFO);
private readonly static Option<SubtitleFormat> SubtitleFormat = new(name: "--sub-format", description: ResString.cmd_subFormat, getDefaultValue: () => Enum.SubtitleFormat.VTT); private readonly static Option<SubtitleFormat> 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), SkipDownload = bindingContext.ParseResult.GetValueForOption(SkipDownload),
WriteMetaJson = bindingContext.ParseResult.GetValueForOption(WriteMetaJson), WriteMetaJson = bindingContext.ParseResult.GetValueForOption(WriteMetaJson),
AppendUrlParams = bindingContext.ParseResult.GetValueForOption(AppendUrlParams), 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<int> InvokeArgs(string[] args, Func<MyOption, Task> action) public static async Task<int> InvokeArgs(string[] args, Func<MyOption, Task> 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, 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 LogLevel, UILanguage
}; };
rootCommand.TreatUnmatchedTokensAsErrors = true; rootCommand.TreatUnmatchedTokensAsErrors = true;

View File

@ -14,6 +14,10 @@ namespace N_m3u8DL_RE.CommandLine
/// </summary> /// </summary>
public string[]? Headers { get; set; } public string[]? Headers { get; set; }
/// <summary> /// <summary>
/// See: <see cref="CommandInvoker.Keys"/>.
/// </summary>
public string[]? Keys { get; set; }
/// <summary>
/// See: <see cref="CommandInvoker.LogLevel"/>. /// See: <see cref="CommandInvoker.LogLevel"/>.
/// </summary> /// </summary>
public LogLevel LogLevel { get; set; } public LogLevel LogLevel { get; set; }
@ -78,6 +82,10 @@ namespace N_m3u8DL_RE.CommandLine
/// </summary> /// </summary>
public string? SaveName { get; set; } public string? SaveName { get; set; }
/// <summary> /// <summary>
/// See: <see cref="CommandInvoker.SavePattern"/>.
/// </summary>
public string? SavePattern { get; set; }
/// <summary>
/// See: <see cref="CommandInvoker.UILanguage"/>. /// See: <see cref="CommandInvoker.UILanguage"/>.
/// </summary> /// </summary>
public string? UILanguage { get; set; } public string? UILanguage { get; set; }

View File

@ -25,6 +25,8 @@ namespace N_m3u8DL_RE.Config
SaveName = option.SaveName; SaveName = option.SaveName;
SaveDir = option.SaveDir; SaveDir = option.SaveDir;
ThreadCount = option.ThreadCount; ThreadCount = option.ThreadCount;
SavePattern = option.SavePattern;
Keys = option.Keys;
} }
/// <summary> /// <summary>
@ -40,6 +42,10 @@ namespace N_m3u8DL_RE.Config
/// </summary> /// </summary>
public string? SaveName { get; set; } public string? SaveName { get; set; }
/// <summary> /// <summary>
/// 文件名模板
/// </summary>
public string? SavePattern { get; set; }
/// <summary>
/// 线程数 /// 线程数
/// </summary> /// </summary>
public int ThreadCount { get; set; } = 8; 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" ["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"
}; };
/// <summary>
/// 解密KEYs
/// </summary>
public string[]? Keys { get; set; }
} }
} }

View File

@ -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 APP_DIR = Path.GetDirectoryName(Environment.ProcessPath)!;
var fileName = "mp4decrypt"; var fileName = "mp4decrypt";
@ -325,7 +325,7 @@ namespace N_m3u8DL_RE.DownloadManager
&& streamSpec.Playlist!.MediaParts.First().MediaSegments.First().EncryptInfo.Method != Common.Enum.EncryptMethod.NONE) && streamSpec.Playlist!.MediaParts.First().MediaSegments.First().EncryptInfo.Method != Common.Enum.EncryptMethod.NONE)
{ {
var enc = output; 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}\""; var cmd = string.Join(" ", DownloaderConfig.Keys.Select(k => $"--key {k}")) + $" \"{enc}\" \"{dec}\"";
Logger.InfoMarkUp($"[grey]Decrypting...[/]"); Logger.InfoMarkUp($"[grey]Decrypting...[/]");
await Process.Start(new ProcessStartInfo() await Process.Start(new ProcessStartInfo()

View File

@ -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://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://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://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 = ""; //url = "";
if (!string.IsNullOrEmpty(option.Input)) if (!string.IsNullOrEmpty(option.Input))
@ -96,6 +97,13 @@ namespace N_m3u8DL_RE
//解析流信息 //解析流信息
var streams = await extractor.ExtractStreamsAsync(); 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); var lists = streams.OrderBy(p => p.MediaType).ThenByDescending(p => p.Bandwidth);
//基本流 //基本流