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); //基本流