Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

默认使用ffmpeg进行mp4解密 #504

Merged
merged 1 commit into from
Nov 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/N_m3u8DL-RE.Common/Resource/ResString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ public class ResString
public static string cmd_uiLanguage => GetText("cmd_uiLanguage");
public static string cmd_urlProcessorArgs => GetText("cmd_urlProcessorArgs");
public static string cmd_useShakaPackager => GetText("cmd_useShakaPackager");
public static string cmd_useMp4decrypt => GetText("cmd_useMp4decrypt");
public static string cmd_concurrentDownload => GetText("cmd_concurrentDownload");
public static string cmd_useSystemProxy => GetText("cmd_useSystemProxy");
public static string cmd_customProxy => GetText("cmd_customProxy");
Expand Down
24 changes: 15 additions & 9 deletions src/N_m3u8DL-RE.Common/Resource/StaticText.cs
Original file line number Diff line number Diff line change
Expand Up @@ -270,9 +270,9 @@ internal class StaticText
),
["cmd_keys"] = new TextContainer
(
zhCN: "设置解密密钥, 程序调用mp4decrpyt/shaka-packager进行解密. 格式:\r\n--key KID1:KEY1 --key KID2:KEY2\r\n对于KEY相同的情况可以直接输入 --key KEY",
zhTW: "設置解密密鑰, 程序調用mp4decrpyt/shaka-packager進行解密. 格式:\r\n--key KID1:KEY1 --key KID2:KEY2\r\n對於KEY相同的情況可以直接輸入 --key KEY",
enUS: "Set decryption key(s) to mp4decrypt/shaka-packager. format:\r\n--key KID1:KEY1 --key KID2:KEY2\r\nor use --key KEY if all tracks share the same key."
zhCN: "设置解密密钥, 程序调用mp4decrpyt/shaka-packager/ffmpeg进行解密. 格式:\r\n--key KID1:KEY1 --key KID2:KEY2\r\n对于KEY相同的情况可以直接输入 --key KEY",
zhTW: "設置解密密鑰, 程序調用mp4decrpyt/shaka-packager/ffmpeg進行解密. 格式:\r\n--key KID1:KEY1 --key KID2:KEY2\r\n對於KEY相同的情況可以直接輸入 --key KEY",
enUS: "Set decryption key(s) to mp4decrypt/shaka-packager/ffmpeg. format:\r\n--key KID1:KEY1 --key KID2:KEY2\r\nor use --key KEY if all tracks share the same key."
),
["cmd_keyText"] = new TextContainer
(
Expand Down Expand Up @@ -468,9 +468,15 @@ internal class StaticText
),
["cmd_useShakaPackager"] = new TextContainer
(
zhCN: "解密时使用shaka-packager替代mp4decrypt",
zhTW: "解密時使用shaka-packager替代mp4decrypt",
enUS: "Use shaka-packager instead of mp4decrypt to decrypt"
zhCN: "解密时使用shaka-packager替代ffmpeg",
zhTW: "解密時使用shaka-packager替代ffmpeg",
enUS: "Use shaka-packager instead of ffmpeg to decrypt"
),
["cmd_useMp4decrypt"] = new TextContainer
(
zhCN: "解密时使用mp4decrypt替代ffmpeg",
zhTW: "解密時使用mp4decrypt替代ffmpeg",
enUS: "Use mp4decrypt instead of ffmpeg to decrypt"
),
["cmd_concurrentDownload"] = new TextContainer
(
Expand Down Expand Up @@ -744,9 +750,9 @@ internal class StaticText
),
["realTimeDecMessage"] = new TextContainer
(
zhCN: "启用实时解密时,建议用shaka-packager而非mp4decrypt",
zhTW: "啟用即時解密時,建議用shaka-packager而非mp4decrypt",
enUS: "When enabling real-time decryption, it is recommended to use shaka-packager instead of mp4decrypt"
zhCN: "启用实时解密时,建议用shaka-packager而非mp4decrypt/ffmpeg",
zhTW: "啟用即時解密時,建議用shaka-packager而非mp4decrypt/ffmpeg",
enUS: "When enabling real-time decryption, it is recommended to use shaka-packager instead of mp4decrypt/ffmpeg"
),
["liveLimitReached"] = new TextContainer
(
Expand Down
4 changes: 3 additions & 1 deletion src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ internal partial class CommandInvoker
private static readonly Option<bool> AppendUrlParams = new(["--append-url-params"], description: ResString.cmd_appendUrlParams, getDefaultValue: () => false);
private static readonly Option<bool> MP4RealTimeDecryption = new (["--mp4-real-time-decryption"], description: ResString.cmd_MP4RealTimeDecryption, getDefaultValue: () => false);
private static readonly Option<bool> UseShakaPackager = new (["--use-shaka-packager"], description: ResString.cmd_useShakaPackager, getDefaultValue: () => false);
private static readonly Option<bool> UseMp4Decrypt = new (["--use-mp4decrypt"], description: ResString.cmd_useMp4decrypt, getDefaultValue: () => false);
private static readonly Option<bool> ForceAnsiConsole = new(["--force-ansi-console"], description: ResString.cmd_forceAnsiConsole);
private static readonly Option<bool> NoAnsiColor = new(["--no-ansi-color"], description: ResString.cmd_noAnsiColor);
private static readonly Option<string?> DecryptionBinaryPath = new(["--decryption-binary-path"], description: ResString.cmd_decryptionBinaryPath) { ArgumentHelpName = "PATH" };
Expand Down Expand Up @@ -523,6 +524,7 @@ protected override MyOption GetBoundValue(BindingContext bindingContext)
UrlProcessorArgs = bindingContext.ParseResult.GetValueForOption(UrlProcessorArgs),
MP4RealTimeDecryption = bindingContext.ParseResult.GetValueForOption(MP4RealTimeDecryption),
UseShakaPackager = bindingContext.ParseResult.GetValueForOption(UseShakaPackager),
UseMp4Decrypt = bindingContext.ParseResult.GetValueForOption(UseMp4Decrypt),
DecryptionBinaryPath = bindingContext.ParseResult.GetValueForOption(DecryptionBinaryPath),
FFmpegBinaryPath = bindingContext.ParseResult.GetValueForOption(FFmpegBinaryPath),
KeyTextFile = bindingContext.ParseResult.GetValueForOption(KeyTextFile),
Expand Down Expand Up @@ -615,7 +617,7 @@ public static async Task<int> InvokeArgs(string[] args, Func<MyOption, Task> act
Input, TmpDir, SaveDir, SaveName, 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, DecryptionBinaryPath, UseShakaPackager, MP4RealTimeDecryption,
LogLevel, UILanguage, UrlProcessorArgs, Keys, KeyTextFile, DecryptionBinaryPath, UseShakaPackager, UseMp4Decrypt, MP4RealTimeDecryption,
MaxSpeed,
MuxAfterDone,
CustomHLSMethod, CustomHLSKey, CustomHLSIv, UseSystemProxy, CustomProxy, CustomRange, TaskStartAt,
Expand Down
13 changes: 13 additions & 0 deletions src/N_m3u8DL-RE/CommandLine/MyOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ internal class MyOption
/// </summary>
public bool UseShakaPackager { get; set; }
/// <summary>
/// See: <see cref="CommandInvoker.UseMp4Decrypt"/>.
/// </summary>
public bool UseMp4Decrypt { get; set; }
/// <summary>
/// See: <see cref="CommandInvoker.MuxAfterDone"/>.
/// </summary>
public bool MuxAfterDone { get; set; }
Expand Down Expand Up @@ -266,4 +270,13 @@ internal class MyOption
/// See: <see cref="CommandInvoker.LiveFixVttByAudio"/>.
/// </summary>
public bool LiveFixVttByAudio { get; set; }

public DecryptEngine GetDecryptEngine()
{
if (UseShakaPackager)
return DecryptEngine.SHAKA_PACKAGE;
if (UseMp4Decrypt)
return DecryptEngine.MP4DECRYPT;
return DecryptEngine.FFMPEG;
}
}
34 changes: 17 additions & 17 deletions src/N_m3u8DL-RE/DownloadManager/SimpleDownloadManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Spectre.Console;
using System.Collections.Concurrent;
using System.Text;
using N_m3u8DL_RE.Enum;

namespace N_m3u8DL_RE.DownloadManager;

Expand All @@ -39,9 +40,9 @@ private async Task SearchKeyAsync(string? currentKID)
if (_key != null)
{
if (DownloaderConfig.MyOptions.Keys == null)
DownloaderConfig.MyOptions.Keys = new string[] { _key };
DownloaderConfig.MyOptions.Keys = [_key];
else
DownloaderConfig.MyOptions.Keys = DownloaderConfig.MyOptions.Keys.Concat(new string[] { _key }).ToArray();
DownloaderConfig.MyOptions.Keys = [..DownloaderConfig.MyOptions.Keys, _key];
}
}

Expand Down Expand Up @@ -109,8 +110,8 @@ private async Task<bool> DownloadStreamAsync(StreamSpec streamSpec, ProgressTask
var saveName = DownloaderConfig.MyOptions.SaveName != null ? $"{DownloaderConfig.MyOptions.SaveName}.{streamSpec.Language}".TrimEnd('.') : dirName;
var headers = DownloaderConfig.Headers;

// mp4decrypt
var mp4decrypt = DownloaderConfig.MyOptions.DecryptionBinaryPath!;
var decryptionBinaryPath = DownloaderConfig.MyOptions.DecryptionBinaryPath!;
var decryptEngine = DownloaderConfig.MyOptions.GetDecryptEngine();
var mp4InitFile = "";
var currentKID = "";
var readInfo = false; // 是否读取过
Expand Down Expand Up @@ -171,7 +172,7 @@ private async Task<bool> DownloadStreamAsync(StreamSpec streamSpec, ProgressTask
currentKID = mp4Info.KID;
// try shaka packager, which can handle WebM
if (string.IsNullOrEmpty(currentKID) && DownloaderConfig.MyOptions.UseShakaPackager) {
currentKID = MP4DecryptUtil.ReadInitShaka(result.ActualFilePath, mp4decrypt);
currentKID = MP4DecryptUtil.ReadInitShaka(result.ActualFilePath, decryptionBinaryPath);
}
// 从文件读取KEY
await SearchKeyAsync(currentKID);
Expand All @@ -180,7 +181,7 @@ private async Task<bool> DownloadStreamAsync(StreamSpec streamSpec, ProgressTask
{
var enc = result.ActualFilePath;
var dec = Path.Combine(Path.GetDirectoryName(enc)!, Path.GetFileNameWithoutExtension(enc) + "_dec" + Path.GetExtension(enc));
var dResult = await MP4DecryptUtil.DecryptAsync(DownloaderConfig.MyOptions.UseShakaPackager, mp4decrypt, DownloaderConfig.MyOptions.Keys, enc, dec, currentKID, isMultiDRM: mp4Info.isMultiDRM);
var dResult = await MP4DecryptUtil.DecryptAsync(decryptEngine, decryptionBinaryPath, DownloaderConfig.MyOptions.Keys, enc, dec, currentKID, isMultiDRM: mp4Info.isMultiDRM);
if (dResult)
{
FileDic[streamSpec.Playlist.MediaInit]!.ActualFilePath = dec;
Expand Down Expand Up @@ -229,7 +230,7 @@ private async Task<bool> DownloadStreamAsync(StreamSpec streamSpec, ProgressTask
// 需要重新解密init
var enc = FileDic[streamSpec.Playlist!.MediaInit!]!.ActualFilePath;
var dec = Path.Combine(Path.GetDirectoryName(enc)!, Path.GetFileNameWithoutExtension(enc) + "_dec" + Path.GetExtension(enc));
var dResult = await MP4DecryptUtil.DecryptAsync(DownloaderConfig.MyOptions.UseShakaPackager, mp4decrypt, DownloaderConfig.MyOptions.Keys, enc, dec, currentKID);
var dResult = await MP4DecryptUtil.DecryptAsync(decryptEngine, decryptionBinaryPath, DownloaderConfig.MyOptions.Keys, enc, dec, currentKID);
if (dResult)
{
FileDic[streamSpec.Playlist!.MediaInit!]!.ActualFilePath = dec;
Expand All @@ -243,7 +244,7 @@ private async Task<bool> DownloadStreamAsync(StreamSpec streamSpec, ProgressTask
}
// try shaka packager, which can handle WebM
if (string.IsNullOrEmpty(currentKID) && DownloaderConfig.MyOptions.UseShakaPackager) {
currentKID = MP4DecryptUtil.ReadInitShaka(result.ActualFilePath, mp4decrypt);
currentKID = MP4DecryptUtil.ReadInitShaka(result.ActualFilePath, decryptionBinaryPath);
}
// 从文件读取KEY
await SearchKeyAsync(currentKID);
Expand All @@ -253,7 +254,7 @@ private async Task<bool> DownloadStreamAsync(StreamSpec streamSpec, ProgressTask
var enc = result.ActualFilePath;
var dec = Path.Combine(Path.GetDirectoryName(enc)!, Path.GetFileNameWithoutExtension(enc) + "_dec" + Path.GetExtension(enc));
mp4Info = MP4DecryptUtil.GetMP4Info(enc);
var dResult = await MP4DecryptUtil.DecryptAsync(DownloaderConfig.MyOptions.UseShakaPackager, mp4decrypt, DownloaderConfig.MyOptions.Keys, enc, dec, currentKID, mp4InitFile, isMultiDRM: mp4Info.isMultiDRM);
var dResult = await MP4DecryptUtil.DecryptAsync(decryptEngine, decryptionBinaryPath, DownloaderConfig.MyOptions.Keys, enc, dec, currentKID, mp4InitFile, isMultiDRM: mp4Info.isMultiDRM);
if (dResult)
{
File.Delete(enc);
Expand Down Expand Up @@ -291,7 +292,7 @@ await Parallel.ForEachAsync(segments, options, async (seg, _) =>
var enc = result.ActualFilePath;
var dec = Path.Combine(Path.GetDirectoryName(enc)!, Path.GetFileNameWithoutExtension(enc) + "_dec" + Path.GetExtension(enc));
mp4Info = MP4DecryptUtil.GetMP4Info(enc);
var dResult = await MP4DecryptUtil.DecryptAsync(DownloaderConfig.MyOptions.UseShakaPackager, mp4decrypt, DownloaderConfig.MyOptions.Keys, enc, dec, currentKID, mp4InitFile, isMultiDRM: mp4Info.isMultiDRM);
var dResult = await MP4DecryptUtil.DecryptAsync(decryptEngine, decryptionBinaryPath, DownloaderConfig.MyOptions.Keys, enc, dec, currentKID, mp4InitFile, isMultiDRM: mp4Info.isMultiDRM);
if (dResult)
{
File.Delete(enc);
Expand Down Expand Up @@ -322,8 +323,8 @@ await Parallel.ForEachAsync(segments, options, async (seg, _) =>
if (!string.IsNullOrEmpty(currentKID) && DownloaderConfig.MyOptions.MP4RealTimeDecryption && DownloaderConfig.MyOptions.Keys != null && DownloaderConfig.MyOptions.Keys.Length > 0 && mp4InitFile != "")
{
File.Delete(mp4InitFile);
// shaka实时解密不需要init文件用于合并
if (DownloaderConfig.MyOptions.UseShakaPackager)
// shaka/ffmpeg实时解密不需要init文件用于合并
if (decryptEngine != DecryptEngine.MP4DECRYPT)
{
FileDic!.Remove(streamSpec.Playlist!.MediaInit, out _);
}
Expand Down Expand Up @@ -590,7 +591,7 @@ await Parallel.ForEachAsync(segments, options, async (seg, _) =>
currentKID = MP4DecryptUtil.GetMP4Info(output).KID;
// try shaka packager, which can handle WebM
if (string.IsNullOrEmpty(currentKID) && DownloaderConfig.MyOptions.UseShakaPackager) {
currentKID = MP4DecryptUtil.ReadInitShaka(output, mp4decrypt);
currentKID = MP4DecryptUtil.ReadInitShaka(output, decryptionBinaryPath);
}
// 从文件读取KEY
await SearchKeyAsync(currentKID);
Expand All @@ -602,8 +603,8 @@ await Parallel.ForEachAsync(segments, options, async (seg, _) =>
var enc = output;
var dec = Path.Combine(Path.GetDirectoryName(enc)!, Path.GetFileNameWithoutExtension(enc) + "_dec" + Path.GetExtension(enc));
mp4Info = MP4DecryptUtil.GetMP4Info(enc);
Logger.InfoMarkUp($"[grey]Decrypting...[/]");
var result = await MP4DecryptUtil.DecryptAsync(DownloaderConfig.MyOptions.UseShakaPackager, mp4decrypt, DownloaderConfig.MyOptions.Keys, enc, dec, currentKID, isMultiDRM: mp4Info.isMultiDRM);
Logger.InfoMarkUp($"[grey]Decrypting using {decryptEngine}...[/]");
var result = await MP4DecryptUtil.DecryptAsync(decryptEngine, decryptionBinaryPath, DownloaderConfig.MyOptions.Keys, enc, dec, currentKID, isMultiDRM: mp4Info.isMultiDRM);
if (result)
{
File.Delete(enc);
Expand Down Expand Up @@ -653,8 +654,7 @@ public async Task<bool> StartDownloadAsync()
}
progress.Columns(progressColumns);

if (DownloaderConfig.MyOptions.MP4RealTimeDecryption && !DownloaderConfig.MyOptions.UseShakaPackager
&& DownloaderConfig.MyOptions.Keys != null && DownloaderConfig.MyOptions.Keys.Length > 0)
if (DownloaderConfig.MyOptions is { MP4RealTimeDecryption: true, UseShakaPackager: false, Keys.Length: > 0 })
Logger.WarnMarkUp($"[darkorange3_1]{ResString.realTimeDecMessage}[/]");

await progress.StartAsync(async ctx =>
Expand Down
Loading