mirror of
https://github.com/NohamR/N_m3u8DL-RE.git
synced 2025-07-08 13:07:07 +00:00
MP4Box support
This commit is contained in:
parent
9a87474411
commit
6b7b030a8b
@ -68,7 +68,7 @@ Options:
|
|||||||
--key KID1:KEY1 --key KID2:KEY2
|
--key KID1:KEY1 --key KID2:KEY2
|
||||||
对于KEY相同的情况可以直接输入 --key KEY
|
对于KEY相同的情况可以直接输入 --key KEY
|
||||||
--key-text-file <key-text-file> 设置密钥文件,程序将从文件中按KID搜寻KEY以解密.(不建议使用特大文件)
|
--key-text-file <key-text-file> 设置密钥文件,程序将从文件中按KID搜寻KEY以解密.(不建议使用特大文件)
|
||||||
--decryption-engine <FFMPEG|MP4DECRYPT|SHAKA_PACKAGER> 设置解密时使用的第三方程序 [default: MP4DECRYPT]
|
--decryption-engine <FFMPEG|MP4DECRYPT|SHAKA_PACKAGER|MP4Box> 设置解密时使用的第三方程序 [default: MP4DECRYPT]
|
||||||
--decryption-binary-path <PATH> MP4解密所用工具的全路径, 例如 C:\Tools\mp4decrypt.exe
|
--decryption-binary-path <PATH> MP4解密所用工具的全路径, 例如 C:\Tools\mp4decrypt.exe
|
||||||
--mp4-real-time-decryption 实时解密MP4分片 [default: False]
|
--mp4-real-time-decryption 实时解密MP4分片 [default: False]
|
||||||
-R, --max-speed <SPEED> 设置限速,单位支持 Mbps 或 Kbps,如:15M 100K
|
-R, --max-speed <SPEED> 设置限速,单位支持 Mbps 或 Kbps,如:15M 100K
|
||||||
|
@ -77,6 +77,7 @@ public static class ResString
|
|||||||
public static string cmd_uiLanguage => GetText("cmd_uiLanguage");
|
public static string cmd_uiLanguage => GetText("cmd_uiLanguage");
|
||||||
public static string cmd_urlProcessorArgs => GetText("cmd_urlProcessorArgs");
|
public static string cmd_urlProcessorArgs => GetText("cmd_urlProcessorArgs");
|
||||||
public static string cmd_useShakaPackager => GetText("cmd_useShakaPackager");
|
public static string cmd_useShakaPackager => GetText("cmd_useShakaPackager");
|
||||||
|
public static string cmd_useMP4Box => GetText("cmd_useMP4Box");
|
||||||
public static string cmd_decryptionEngine => GetText("cmd_decryptionEngine");
|
public static string cmd_decryptionEngine => GetText("cmd_decryptionEngine");
|
||||||
public static string cmd_concurrentDownload => GetText("cmd_concurrentDownload");
|
public static string cmd_concurrentDownload => GetText("cmd_concurrentDownload");
|
||||||
public static string cmd_useSystemProxy => GetText("cmd_useSystemProxy");
|
public static string cmd_useSystemProxy => GetText("cmd_useSystemProxy");
|
||||||
@ -108,6 +109,7 @@ public static class ResString
|
|||||||
public static string mkvmergeNotFound => GetText("mkvmergeNotFound");
|
public static string mkvmergeNotFound => GetText("mkvmergeNotFound");
|
||||||
public static string mp4decryptNotFound => GetText("mp4decryptNotFound");
|
public static string mp4decryptNotFound => GetText("mp4decryptNotFound");
|
||||||
public static string shakaPackagerNotFound => GetText("shakaPackagerNotFound");
|
public static string shakaPackagerNotFound => GetText("shakaPackagerNotFound");
|
||||||
|
public static string mp4boxNotFound => GetText("mp4boxNotFound");
|
||||||
public static string fixingTTML => GetText("fixingTTML");
|
public static string fixingTTML => GetText("fixingTTML");
|
||||||
public static string fixingTTMLmp4 => GetText("fixingTTMLmp4");
|
public static string fixingTTMLmp4 => GetText("fixingTTMLmp4");
|
||||||
public static string fixingVTT => GetText("fixingVTT");
|
public static string fixingVTT => GetText("fixingVTT");
|
||||||
|
@ -466,6 +466,12 @@ internal static class StaticText
|
|||||||
zhTW: "解密時使用shaka-packager替代mp4decrypt",
|
zhTW: "解密時使用shaka-packager替代mp4decrypt",
|
||||||
enUS: "Use shaka-packager instead of mp4decrypt to decrypt"
|
enUS: "Use shaka-packager instead of mp4decrypt to decrypt"
|
||||||
),
|
),
|
||||||
|
["cmd_useMP4Box"] = new TextContainer
|
||||||
|
(
|
||||||
|
zhCN: "解密时使用MP4Box替代mp4decrypt",
|
||||||
|
zhTW: "解密時使用MP4Box替代mp4decrypt",
|
||||||
|
enUS: "Use MP4Box instead of mp4decrypt to decrypt"
|
||||||
|
),
|
||||||
["cmd_decryptionEngine"] = new TextContainer
|
["cmd_decryptionEngine"] = new TextContainer
|
||||||
(
|
(
|
||||||
zhCN: "设置解密时使用的第三方程序",
|
zhCN: "设置解密时使用的第三方程序",
|
||||||
@ -790,6 +796,12 @@ internal static class StaticText
|
|||||||
zhTW: "找不到shaka-packager,請自行下載:https://github.com/shaka-project/shaka-packager/releases",
|
zhTW: "找不到shaka-packager,請自行下載:https://github.com/shaka-project/shaka-packager/releases",
|
||||||
enUS: "shaka-packager not found, please download at: https://github.com/shaka-project/shaka-packager/releases"
|
enUS: "shaka-packager not found, please download at: https://github.com/shaka-project/shaka-packager/releases"
|
||||||
),
|
),
|
||||||
|
["mp4boxNotFound"] = new TextContainer
|
||||||
|
(
|
||||||
|
zhCN: "找不到MP4Box,请自行下载:https://github.com/gpac/gpac/",
|
||||||
|
zhTW: "找不到MP4Box,請自行下載:https://github.com/gpac/gpac/",
|
||||||
|
enUS: "MP4Box not found, please download at: https://github.com/gpac/gpac/"
|
||||||
|
),
|
||||||
["mp4decryptNotFound"] = new TextContainer
|
["mp4decryptNotFound"] = new TextContainer
|
||||||
(
|
(
|
||||||
zhCN: "找不到mp4decrypt,请自行下载:https://www.bento4.com/downloads/",
|
zhCN: "找不到mp4decrypt,请自行下载:https://www.bento4.com/downloads/",
|
||||||
|
@ -36,8 +36,8 @@ public partial class MSSMoovProcessor
|
|||||||
private bool IsProtection;
|
private bool IsProtection;
|
||||||
private string ProtectionSystemId;
|
private string ProtectionSystemId;
|
||||||
private string ProtectionData;
|
private string ProtectionData;
|
||||||
private string? ProtecitonKID;
|
private string? ProtectionKID;
|
||||||
private string? ProtecitonKID_PR;
|
private string? ProtectionKID_PR;
|
||||||
private byte[] UnityMatrix
|
private byte[] UnityMatrix
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -166,17 +166,18 @@ public partial class MSSMoovProcessor
|
|||||||
var text = Encoding.ASCII.GetString(bytes);
|
var text = Encoding.ASCII.GetString(bytes);
|
||||||
var kidBytes = Convert.FromBase64String(KIDRegex().Match(text).Groups[1].Value);
|
var kidBytes = Convert.FromBase64String(KIDRegex().Match(text).Groups[1].Value);
|
||||||
// save kid for playready
|
// save kid for playready
|
||||||
this.ProtecitonKID_PR = HexUtil.BytesToHex(kidBytes);
|
this.ProtectionKID_PR = HexUtil.BytesToHex(kidBytes);
|
||||||
// fix byte order
|
// fix byte order
|
||||||
var reverse1 = new[] { kidBytes[3], kidBytes[2], kidBytes[1], kidBytes[0] };
|
var reverse1 = new[] { kidBytes[3], kidBytes[2], kidBytes[1], kidBytes[0] };
|
||||||
var reverse2 = new[] { kidBytes[5], kidBytes[4], kidBytes[7], kidBytes[6] };
|
var reverse2 = new[] { kidBytes[5], kidBytes[4], kidBytes[7], kidBytes[6] };
|
||||||
Array.Copy(reverse1, 0, kidBytes, 0, reverse1.Length);
|
Array.Copy(reverse1, 0, kidBytes, 0, reverse1.Length);
|
||||||
Array.Copy(reverse2, 0, kidBytes, 4, reverse1.Length);
|
Array.Copy(reverse2, 0, kidBytes, 4, reverse1.Length);
|
||||||
this.ProtecitonKID = HexUtil.BytesToHex(kidBytes);
|
this.ProtectionKID = HexUtil.BytesToHex(kidBytes);
|
||||||
}
|
}
|
||||||
// widevine
|
// widevine
|
||||||
else if (ProtectionSystemId.ToUpper() == "EDEF8BA9-79D6-4ACE-A3C8-27DCD51D21ED")
|
else if (ProtectionSystemId.ToUpper() == "EDEF8BA9-79D6-4ACE-A3C8-27DCD51D21ED")
|
||||||
{
|
{
|
||||||
|
// Console.WriteLine($"WV Protection Data: {ProtectionData}");
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -225,7 +226,7 @@ public partial class MSSMoovProcessor
|
|||||||
tencPayload.AddRange([0, 0]);
|
tencPayload.AddRange([0, 0]);
|
||||||
tencPayload.Add(0x1); // default_IsProtected
|
tencPayload.Add(0x1); // default_IsProtected
|
||||||
tencPayload.Add(0x8); // default_Per_Sample_IV_size
|
tencPayload.Add(0x8); // default_Per_Sample_IV_size
|
||||||
tencPayload.AddRange(HexUtil.HexToBytes(ProtecitonKID)); // default_KID
|
tencPayload.AddRange(HexUtil.HexToBytes(ProtectionKID)); // default_KID
|
||||||
// tencPayload.Add(0x8);// default_constant_IV_size
|
// tencPayload.Add(0x8);// default_constant_IV_size
|
||||||
// tencPayload.AddRange(new byte[8]);// default_constant_IV
|
// tencPayload.AddRange(new byte[8]);// default_constant_IV
|
||||||
var tencBox = FullBox("tenc", 0, 0, tencPayload.ToArray());
|
var tencBox = FullBox("tenc", 0, 0, tencPayload.ToArray());
|
||||||
@ -753,10 +754,10 @@ public partial class MSSMoovProcessor
|
|||||||
using var _stream = new MemoryStream();
|
using var _stream = new MemoryStream();
|
||||||
using var _writer = new BinaryWriter2(_stream);
|
using var _writer = new BinaryWriter2(_stream);
|
||||||
var sysIdData = HexUtil.HexToBytes("edef8ba9-79d6-4ace-a3c8-27dcd51d21ed".Replace("-", ""));
|
var sysIdData = HexUtil.HexToBytes("edef8ba9-79d6-4ace-a3c8-27dcd51d21ed".Replace("-", ""));
|
||||||
// var kid = HexUtil.HexToBytes(ProtecitonKID);
|
// var kid = HexUtil.HexToBytes(ProtectionKID);
|
||||||
|
|
||||||
_writer.Write(sysIdData); // SystemID 16 bytes
|
_writer.Write(sysIdData); // SystemID 16 bytes
|
||||||
var psshData = HexUtil.HexToBytes($"08011210{ProtecitonKID}1A046E647265220400000000");
|
var psshData = HexUtil.HexToBytes($"08011210{ProtectionKID}1A046E647265220400000000");
|
||||||
_writer.WriteUInt(psshData.Length); // Size of Data 4 bytes
|
_writer.WriteUInt(psshData.Length); // Size of Data 4 bytes
|
||||||
_writer.Write(psshData); // Data
|
_writer.Write(psshData); // Data
|
||||||
var psshBox = FullBox("pssh", 0, 0, _stream.ToArray());
|
var psshBox = FullBox("pssh", 0, 0, _stream.ToArray());
|
||||||
|
@ -17,7 +17,7 @@ namespace N_m3u8DL_RE.CommandLine;
|
|||||||
|
|
||||||
internal static partial class CommandInvoker
|
internal static partial class CommandInvoker
|
||||||
{
|
{
|
||||||
public const string VERSION_INFO = "N_m3u8DL-RE (Beta version) 20241216";
|
public const string VERSION_INFO = "N_m3u8DL-RE (Beta version) by noham";
|
||||||
|
|
||||||
[GeneratedRegex("((best|worst)\\d*|all)")]
|
[GeneratedRegex("((best|worst)\\d*|all)")]
|
||||||
private static partial Regex ForStrRegex();
|
private static partial Regex ForStrRegex();
|
||||||
@ -56,6 +56,7 @@ internal static partial class CommandInvoker
|
|||||||
private static readonly Option<bool> AppendUrlParams = new(["--append-url-params"], description: ResString.cmd_appendUrlParams, getDefaultValue: () => false);
|
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> 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) { IsHidden = true };
|
private static readonly Option<bool> UseShakaPackager = new (["--use-shaka-packager"], description: ResString.cmd_useShakaPackager, getDefaultValue: () => false) { IsHidden = true };
|
||||||
|
private static readonly Option<bool> UseMP4Box = new (["--use-mp4box"], description: ResString.cmd_useMP4Box, getDefaultValue: () => false) { IsHidden = true };
|
||||||
private static readonly Option<DecryptEngine> DecryptionEngine = new (["--decryption-engine"], description: ResString.cmd_decryptionEngine, getDefaultValue: () => DecryptEngine.MP4DECRYPT);
|
private static readonly Option<DecryptEngine> DecryptionEngine = new (["--decryption-engine"], description: ResString.cmd_decryptionEngine, getDefaultValue: () => DecryptEngine.MP4DECRYPT);
|
||||||
private static readonly Option<bool> ForceAnsiConsole = new(["--force-ansi-console"], description: ResString.cmd_forceAnsiConsole);
|
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<bool> NoAnsiColor = new(["--no-ansi-color"], description: ResString.cmd_noAnsiColor);
|
||||||
@ -525,6 +526,7 @@ internal static partial class CommandInvoker
|
|||||||
UrlProcessorArgs = bindingContext.ParseResult.GetValueForOption(UrlProcessorArgs),
|
UrlProcessorArgs = bindingContext.ParseResult.GetValueForOption(UrlProcessorArgs),
|
||||||
MP4RealTimeDecryption = bindingContext.ParseResult.GetValueForOption(MP4RealTimeDecryption),
|
MP4RealTimeDecryption = bindingContext.ParseResult.GetValueForOption(MP4RealTimeDecryption),
|
||||||
UseShakaPackager = bindingContext.ParseResult.GetValueForOption(UseShakaPackager),
|
UseShakaPackager = bindingContext.ParseResult.GetValueForOption(UseShakaPackager),
|
||||||
|
UseMP4Box = bindingContext.ParseResult.GetValueForOption(UseMP4Box),
|
||||||
DecryptionEngine = bindingContext.ParseResult.GetValueForOption(DecryptionEngine),
|
DecryptionEngine = bindingContext.ParseResult.GetValueForOption(DecryptionEngine),
|
||||||
DecryptionBinaryPath = bindingContext.ParseResult.GetValueForOption(DecryptionBinaryPath),
|
DecryptionBinaryPath = bindingContext.ParseResult.GetValueForOption(DecryptionBinaryPath),
|
||||||
FFmpegBinaryPath = bindingContext.ParseResult.GetValueForOption(FFmpegBinaryPath),
|
FFmpegBinaryPath = bindingContext.ParseResult.GetValueForOption(FFmpegBinaryPath),
|
||||||
@ -616,7 +618,7 @@ internal static partial class CommandInvoker
|
|||||||
Input, TmpDir, SaveDir, SaveName, BaseUrl, ThreadCount, DownloadRetryCount, HttpRequestTimeout, ForceAnsiConsole, NoAnsiColor,AutoSelect, SkipMerge, SkipDownload, CheckSegmentsCount,
|
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,
|
BinaryMerge, UseFFmpegConcatDemuxer, DelAfterDone, NoDateInfo, NoLog, WriteMetaJson, AppendUrlParams, ConcurrentDownload, Headers, /**SavePattern,**/ SubOnly, SubtitleFormat, AutoSubtitleFix,
|
||||||
FFmpegBinaryPath,
|
FFmpegBinaryPath,
|
||||||
LogLevel, UILanguage, UrlProcessorArgs, Keys, KeyTextFile, DecryptionEngine, DecryptionBinaryPath, UseShakaPackager, MP4RealTimeDecryption,
|
LogLevel, UILanguage, UrlProcessorArgs, Keys, KeyTextFile, DecryptionEngine, DecryptionBinaryPath, UseShakaPackager, UseMP4Box, MP4RealTimeDecryption,
|
||||||
MaxSpeed,
|
MaxSpeed,
|
||||||
MuxAfterDone,
|
MuxAfterDone,
|
||||||
CustomHLSMethod, CustomHLSKey, CustomHLSIv, UseSystemProxy, CustomProxy, CustomRange, TaskStartAt,
|
CustomHLSMethod, CustomHLSKey, CustomHLSIv, UseSystemProxy, CustomProxy, CustomRange, TaskStartAt,
|
||||||
|
@ -144,6 +144,10 @@ internal class MyOption
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// See: <see cref="CommandInvoker.DecryptionEngine"/>.
|
/// See: <see cref="CommandInvoker.DecryptionEngine"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
public bool UseMP4Box { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// See: <see cref="CommandInvoker.DecryptionEngine"/>.
|
||||||
|
/// </summary>
|
||||||
public DecryptEngine DecryptionEngine { get; set; }
|
public DecryptEngine DecryptionEngine { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// See: <see cref="CommandInvoker.MuxAfterDone"/>.
|
/// See: <see cref="CommandInvoker.MuxAfterDone"/>.
|
||||||
|
@ -4,5 +4,6 @@ internal enum DecryptEngine
|
|||||||
{
|
{
|
||||||
MP4DECRYPT,
|
MP4DECRYPT,
|
||||||
SHAKA_PACKAGER,
|
SHAKA_PACKAGER,
|
||||||
|
MP4BOX,
|
||||||
FFMPEG,
|
FFMPEG,
|
||||||
}
|
}
|
@ -126,6 +126,10 @@ internal class Program
|
|||||||
{
|
{
|
||||||
option.DecryptionEngine = DecryptEngine.SHAKA_PACKAGER;
|
option.DecryptionEngine = DecryptEngine.SHAKA_PACKAGER;
|
||||||
}
|
}
|
||||||
|
if (option.UseMP4Box)
|
||||||
|
{
|
||||||
|
option.DecryptionEngine = DecryptEngine.MP4BOX;
|
||||||
|
}
|
||||||
|
|
||||||
// LivePipeMux开启时 LiveRealTimeMerge必须开启
|
// LivePipeMux开启时 LiveRealTimeMerge必须开启
|
||||||
if (option is { LivePipeMux: true, LiveRealTimeMerge: false })
|
if (option is { LivePipeMux: true, LiveRealTimeMerge: false })
|
||||||
@ -184,6 +188,14 @@ internal class Program
|
|||||||
Logger.Extra($"mp4decrypt => {option.DecryptionBinaryPath}");
|
Logger.Extra($"mp4decrypt => {option.DecryptionBinaryPath}");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DecryptEngine.MP4BOX:
|
||||||
|
{
|
||||||
|
var file = GlobalUtil.FindExecutable("MP4Box");
|
||||||
|
if (file == null) throw new FileNotFoundException(ResString.mp4boxNotFound);
|
||||||
|
option.DecryptionBinaryPath = file;
|
||||||
|
Logger.Extra($"MP4Box => {option.DecryptionBinaryPath}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
case DecryptEngine.FFMPEG:
|
case DecryptEngine.FFMPEG:
|
||||||
default:
|
default:
|
||||||
option.DecryptionBinaryPath = option.FFmpegBinaryPath;
|
option.DecryptionBinaryPath = option.FFmpegBinaryPath;
|
||||||
|
@ -51,7 +51,7 @@ internal static partial class MP4DecryptUtil
|
|||||||
// shakaPackager/ffmpeg 无法单独解密init文件
|
// shakaPackager/ffmpeg 无法单独解密init文件
|
||||||
if (source.EndsWith("_init.mp4") && decryptEngine != DecryptEngine.MP4DECRYPT) return false;
|
if (source.EndsWith("_init.mp4") && decryptEngine != DecryptEngine.MP4DECRYPT) return false;
|
||||||
|
|
||||||
string cmd;
|
string cmd = "";
|
||||||
|
|
||||||
var tmpFile = "";
|
var tmpFile = "";
|
||||||
if (decryptEngine == DecryptEngine.SHAKA_PACKAGER)
|
if (decryptEngine == DecryptEngine.SHAKA_PACKAGER)
|
||||||
@ -67,6 +67,55 @@ internal static partial class MP4DecryptUtil
|
|||||||
|
|
||||||
cmd = $"--quiet --enable_raw_key_decryption input=\"{enc}\",stream=0,output=\"{dest}\" " +
|
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]}";
|
$"--keys {(trackId != null ? $"label={trackId}:" : "")}key_id={(trackId != null ? ZeroKid : kid)}:key={keyPair.Split(':')[1]}";
|
||||||
|
}
|
||||||
|
else if (decryptEngine == DecryptEngine.MP4BOX)
|
||||||
|
{
|
||||||
|
// Logger.Info($"decryptEngine: {decryptEngine}"); // decryptEngine: MP4BOX
|
||||||
|
// Logger.Info($"bin: {bin}"); // bin: /Applications/GPAC.app/Contents/MacOS/MP4Box
|
||||||
|
// Logger.Info($"keys: {string.Join(", ", keys ?? new string[0])}"); // keys: ccbf5fb4c2965be7aa130ffb3ba9fd73:9cc0c92044cb1d69433f5f5839a159df, 9bf0e9cf0d7b55aeb4b289a63bab8610:90f52fd8ca48717b21d0c2fed7a12ae1, eb676abbcb345e96bbcf616630f1a3da:100b6c20940f779a4589152b57d2dacb, 0294b9599d755de2bbf0fdca3fa5eab7:3bda2f40344c7def614227b9c0f03e26, 639da80cf23b55f3b8cab3f64cfa5df6:229f5f29b643e203004b30c4eaf348f4
|
||||||
|
// Logger.Info($"source: {source}"); // source: /Users/noham/Documents/clone/N_m3u8DL-RE/artifact-arm64/11331_2025-02-01_20-04-27.mp4
|
||||||
|
// Logger.Info($"dest: {dest}"); // dest: /Users/noham/Documents/clone/N_m3u8DL-RE/artifact-arm64/11331_2025-02-01_20-04-27_dec.mp4
|
||||||
|
// Logger.Info($"kid: {kid}"); // kid: eb676abbcb345e96bbcf616630f1a3da
|
||||||
|
// Logger.Info($"init: {init}"); // init:
|
||||||
|
// Logger.Info($"isMultiDRM: {isMultiDRM}"); // isMultiDRM: False
|
||||||
|
// Logger.Info($"trackId: {trackId}"); // trackId:
|
||||||
|
// Logger.Info($"keyPair: {keyPair}"); // keyPair: eb676abbcb345e96bbcf616630f1a3da:100b6c20940f779a4589152b57d2dacb
|
||||||
|
// Logger.Info($"tmpEncFile: {tmpEncFile}"); // tmpEncFile:
|
||||||
|
// Logger.Info($"tmpDecFile: {tmpDecFile}"); // tmpDecFile:
|
||||||
|
// Logger.Info($"workDir: {workDir}"); // workDir:
|
||||||
|
// Logger.Info($"tmpFile: {tmpFile}"); // tmpFile:
|
||||||
|
|
||||||
|
var name = Path.GetFileNameWithoutExtension(source);
|
||||||
|
// Logger.Info($"name: {name}");
|
||||||
|
|
||||||
|
workDir = Path.GetDirectoryName(source)!;
|
||||||
|
|
||||||
|
var enc = source;
|
||||||
|
if (init != "")
|
||||||
|
{
|
||||||
|
var mergedinitenc = Path.ChangeExtension(source, ".itmp");
|
||||||
|
MergeUtil.CombineMultipleFilesIntoSingleFile([init, source], mergedinitenc);
|
||||||
|
enc = mergedinitenc;
|
||||||
|
}
|
||||||
|
// Logger.Info($"enc: {enc}");
|
||||||
|
|
||||||
|
var xmlfile = Path.Combine(workDir, $"{name}_drm.xml.itmp");
|
||||||
|
tmpFile = xmlfile;
|
||||||
|
var xmlContent = $"""
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<GPACDRM type="CENC">
|
||||||
|
<CrypTrack trackID="1">
|
||||||
|
<key KID="{keyPair.Split(':')[0]}" value="{keyPair.Split(':')[1]}"/>
|
||||||
|
</CrypTrack>
|
||||||
|
</GPACDRM>
|
||||||
|
""";
|
||||||
|
File.WriteAllText(xmlfile, xmlContent);
|
||||||
|
|
||||||
|
// Logger.Info($"xmlfile: {xmlfile}");
|
||||||
|
// Logger.Info($"Decrypting {Path.GetFileName(enc)} using MP4Box");
|
||||||
|
cmd = $"-decrypt \"{xmlfile}\" \"{enc}\" -out \"{dest}\" -logs=all@error"; // f"MP4Box -decrypt {xmlfile} {file} -out {file} -logs=all@error"
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (decryptEngine == DecryptEngine.MP4DECRYPT)
|
else if (decryptEngine == DecryptEngine.MP4DECRYPT)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user