diff --git a/src/N_m3u8DL-RE.Parser/Processor/HLS/DefaultHLSContentProcessor.cs b/src/N_m3u8DL-RE.Parser/Processor/HLS/DefaultHLSContentProcessor.cs
index 260fbca..47535f4 100644
--- a/src/N_m3u8DL-RE.Parser/Processor/HLS/DefaultHLSContentProcessor.cs
+++ b/src/N_m3u8DL-RE.Parser/Processor/HLS/DefaultHLSContentProcessor.cs
@@ -22,6 +22,8 @@ namespace N_m3u8DL_RE.Parser.Processor.HLS
private static partial Regex OrderFixRegex();
[GeneratedRegex("#EXT-X-MAP.*\\.apple\\.com/")]
private static partial Regex ATVRegex();
+ [GeneratedRegex("(#EXT-X-KEY:[\\s\\S]*?)(#EXT-X-DISCONTINUITY|#EXT-X-ENDLIST)")]
+ private static partial Regex ATVRegex2();
public override bool CanProcess(ExtractorType extractorType, string rawText, ParserConfig parserConfig) => extractorType == ExtractorType.HLS;
@@ -80,7 +82,7 @@ namespace N_m3u8DL_RE.Parser.Processor.HLS
if (m3u8Content.Contains("#EXT-X-DISCONTINUITY") && m3u8Content.Contains("#EXT-X-MAP") && (m3u8Url.Contains(".apple.com/") || ATVRegex().IsMatch(m3u8Content)))
{
//只取加密部分即可
- Regex ykmap = DNSPRegex();
+ Regex ykmap = ATVRegex2();
if (ykmap.IsMatch(m3u8Content))
{
m3u8Content = "#EXTM3U\r\n" + ykmap.Match(m3u8Content).Groups[1].Value + "\r\n#EXT-X-ENDLIST";
diff --git a/src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs b/src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs
index 07d0b92..feea8c7 100644
--- a/src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs
+++ b/src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs
@@ -18,7 +18,7 @@ namespace N_m3u8DL_RE.CommandLine
{
internal partial class CommandInvoker
{
- public const string VERSION_INFO = "N_m3u8DL-RE (Beta version) 20221212";
+ public const string VERSION_INFO = "N_m3u8DL-RE (Beta version) 20221220";
[GeneratedRegex("((best|worst)\\d*|all)")]
private static partial Regex ForStrRegex();
diff --git a/src/N_m3u8DL-RE/DownloadManager/SimpleDownloadManager.cs b/src/N_m3u8DL-RE/DownloadManager/SimpleDownloadManager.cs
index addc7ff..eef2469 100644
--- a/src/N_m3u8DL-RE/DownloadManager/SimpleDownloadManager.cs
+++ b/src/N_m3u8DL-RE/DownloadManager/SimpleDownloadManager.cs
@@ -323,7 +323,7 @@ namespace N_m3u8DL_RE.DownloadManager
//校验分片数量
if (DownloaderConfig.MyOptions.CheckSegmentsCount && FileDic.Values.Any(s => s == null))
{
- Logger.WarnMarkUp(ResString.segmentCountCheckNotPass, totalCount, FileDic.Values.Where(s => s != null).Count());
+ Logger.ErrorMarkUp(ResString.segmentCountCheckNotPass, totalCount, FileDic.Values.Where(s => s != null).Count());
return false;
}
@@ -670,6 +670,8 @@ namespace N_m3u8DL_RE.DownloadManager
var task = kp.Value;
var result = await DownloadStreamAsync(kp.Key, task, SpeedContainerDic[task.Id]);
Results[kp.Key] = result;
+ //失败不再下载后续
+ if (!result) break;
}
}
else
diff --git a/src/N_m3u8DL-RE/DownloadManager/SimpleLiveRecordManager2.cs b/src/N_m3u8DL-RE/DownloadManager/SimpleLiveRecordManager2.cs
index 6892add..401106e 100644
--- a/src/N_m3u8DL-RE/DownloadManager/SimpleLiveRecordManager2.cs
+++ b/src/N_m3u8DL-RE/DownloadManager/SimpleLiveRecordManager2.cs
@@ -799,7 +799,7 @@ namespace N_m3u8DL_RE.DownloadManager
//创建任务
var dic = SelectedSteams.Select(item =>
{
- var task = ctx.AddTask(item.ToShortString(), autoStart: false, maxValue: 0);
+ var task = ctx.AddTask(item.ToShortShortString(), autoStart: false, maxValue: 0);
SpeedContainerDic[task.Id] = new SpeedContainer(); //速度计算
LastFileNameDic[task.Id] = "";
DateTimeDic[task.Id] = 0L;
diff --git a/src/N_m3u8DL-RE/Downloader/SimpleDownloader.cs b/src/N_m3u8DL-RE/Downloader/SimpleDownloader.cs
index 4780a08..1fe73a2 100644
--- a/src/N_m3u8DL-RE/Downloader/SimpleDownloader.cs
+++ b/src/N_m3u8DL-RE/Downloader/SimpleDownloader.cs
@@ -85,12 +85,19 @@ namespace N_m3u8DL_RE.Downloader
cancellationTokenSource = new();
var des = Path.ChangeExtension(path, null);
- //已下载过跳过
+ //已下载跳过
if (File.Exists(des))
{
return new DownloadResult() { ActualContentLength = 0, ActualFilePath = des };
}
+ //已解密跳过
+ var dec = Path.Combine(Path.GetDirectoryName(des)!, Path.GetFileNameWithoutExtension(des) + "_dec" + Path.GetExtension(des));
+ if (File.Exists(dec))
+ {
+ return new DownloadResult() { ActualContentLength = 0, ActualFilePath = dec };
+ }
+
//另起线程进行监控
using var watcher = Task.Factory.StartNew(async () =>
{
@@ -128,6 +135,10 @@ namespace N_m3u8DL_RE.Downloader
await Task.Delay(1000);
goto retry;
}
+ else
+ {
+ Logger.WarnMarkUp($"[grey]{ex.Message.EscapeMarkup()}[/]");
+ }
//throw new Exception("download failed", ex);
return null;
}
diff --git a/src/N_m3u8DL-RE/N_m3u8DL-RE.csproj b/src/N_m3u8DL-RE/N_m3u8DL-RE.csproj
index 99c4537..e9274da 100644
--- a/src/N_m3u8DL-RE/N_m3u8DL-RE.csproj
+++ b/src/N_m3u8DL-RE/N_m3u8DL-RE.csproj
@@ -7,7 +7,7 @@
enable
preview
enable
- 0.1.5
+ 0.1.5.2
AnyCPU;x64
diff --git a/src/N_m3u8DL-RE/Util/MP4DecryptUtil.cs b/src/N_m3u8DL-RE/Util/MP4DecryptUtil.cs
index cab5038..99b8f3b 100644
--- a/src/N_m3u8DL-RE/Util/MP4DecryptUtil.cs
+++ b/src/N_m3u8DL-RE/Util/MP4DecryptUtil.cs
@@ -7,17 +7,26 @@ namespace N_m3u8DL_RE.Util
{
internal class MP4DecryptUtil
{
+ private static string ZeroKid = "00000000000000000000000000000000";
public static async Task DecryptAsync(bool shakaPackager, string bin, string[]? keys, string source, string dest, string? kid, string init = "")
{
if (keys == null || keys.Length == 0) return false;
- var keyPair = keys.First();
+ string? keyPair = null;
+ string? trackId = null;
if (!string.IsNullOrEmpty(kid))
{
var test = keys.Where(k => k.StartsWith(kid));
if (test.Any()) keyPair = test.First();
}
+ //Apple
+ if (kid == ZeroKid)
+ {
+ keyPair = keys.First();
+ trackId = "1";
+ }
+
if (keyPair == null) return false;
//shakaPackager 无法单独解密init文件
@@ -37,12 +46,19 @@ namespace N_m3u8DL_RE.Util
enc = tmpFile;
}
- cmd = $"--enable_raw_key_decryption input=\"{enc}\",stream=0,output=\"{dest}\" " +
- $"--keys key_id={keyPair.Split(':')[0]}:key={keyPair.Split(':')[1]}";
+ cmd = $"--quiet --enable_raw_key_decryption input=\"{enc}\",stream=0,output=\"{dest}\" " +
+ $"--keys {(trackId != null ? $"label={trackId}:" : "")}key_id={(trackId != null ? ZeroKid : kid)}:key={keyPair.Split(':')[1]}";
}
else
{
- cmd = string.Join(" ", keys.Select(k => $"--key {k}"));
+ if (trackId == null)
+ {
+ cmd = string.Join(" ", keys.Select(k => $"--key {k}"));
+ }
+ else
+ {
+ cmd = string.Join(" ", keys.Select(k => $"--key {trackId}:{k.Split(':')[1]}"));
+ }
if (init != "")
{
cmd += $" --fragments-info \"{init}\" ";
@@ -69,8 +85,8 @@ namespace N_m3u8DL_RE.Util
{
FileName = name,
Arguments = arg,
- RedirectStandardOutput = true,
- RedirectStandardError = true,
+ //RedirectStandardOutput = true,
+ //RedirectStandardError = true,
CreateNoWindow = true,
UseShellExecute = false
})!.WaitForExitAsync();