Compare commits

...

No commits in common. "948f7aa75a7741644dde8fd8dfb3581e899a22f9" and "d48f7e58fec3167d2a0652aa3265e4178b2f5ed5" have entirely different histories.

13 changed files with 143 additions and 69 deletions

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

13
.github/FUNDING.yml vendored
View File

@ -1,13 +0,0 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
custom: ['https://nilaoda.github.io/N_m3u8DL-CLI/source/images/alipay.png','https://www.buymeacoffee.com/nilaoda']

View File

@ -71,7 +71,7 @@ jobs:
zip ../N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_win-NT6.0-x86_${{ needs.set-date.outputs.date }}.zip N_m3u8DL-RE.exe
- name: Upload Artifact[win-x86]
uses: actions/upload-artifact@v3.1.3
uses: actions/upload-artifact@v4
with:
name: win-NT6.0-x86
path: N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_win-NT6.0-x86_${{ needs.set-date.outputs.date }}.zip
@ -102,62 +102,62 @@ jobs:
zip ../N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_win-arm64_${{ needs.set-date.outputs.date }}.zip N_m3u8DL-RE.exe
- name: Upload Artifact [win-x64]
uses: actions/upload-artifact@v3.1.3
uses: actions/upload-artifact@v4
with:
name: win-x64
path: N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_win-x64_${{ needs.set-date.outputs.date }}.zip
- name: Upload Artifact [win-arm64]
uses: actions/upload-artifact@v3.1.3
uses: actions/upload-artifact@v4
with:
name: win-arm64
path: N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_win-arm64_${{ needs.set-date.outputs.date }}.zip
build-linux-x64-arm64:
runs-on: ubuntu-latest
needs: set-date
# build-linux-x64-arm64:
# runs-on: ubuntu-latest
# needs: set-date
steps:
# https://learn.microsoft.com/zh-cn/dotnet/core/deploying/native-aot/cross-compile
- run: |
sudo dpkg --add-architecture arm64
sudo bash -c 'cat > /etc/apt/sources.list.d/arm64.list <<EOF
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy main restricted
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy-updates main restricted
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy-backports main restricted universe multiverse
EOF'
sudo sed -i -e 's/deb http/deb [arch=amd64] http/g' /etc/apt/sources.list
sudo sed -i -e 's/deb mirror/deb [arch=amd64] mirror/g' /etc/apt/sources.list
sudo apt-get update
sudo apt-get install -y curl wget libicu-dev libcurl4-openssl-dev zlib1g-dev libkrb5-dev clang llvm binutils-aarch64-linux-gnu gcc-aarch64-linux-gnu zlib1g-dev:arm64
# steps:
# # https://learn.microsoft.com/zh-cn/dotnet/core/deploying/native-aot/cross-compile
# - run: |
# sudo dpkg --add-architecture arm64
# sudo bash -c 'cat > /etc/apt/sources.list.d/arm64.list <<EOF
# deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy main restricted
# deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy-updates main restricted
# deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy-backports main restricted universe multiverse
# EOF'
# sudo sed -i -e 's/deb http/deb [arch=amd64] http/g' /etc/apt/sources.list
# sudo sed -i -e 's/deb mirror/deb [arch=amd64] mirror/g' /etc/apt/sources.list
# sudo apt-get update
# sudo apt-get install -y curl wget libicu-dev libcurl4-openssl-dev zlib1g-dev libkrb5-dev clang llvm binutils-aarch64-linux-gnu gcc-aarch64-linux-gnu zlib1g-dev:arm64
- uses: actions/checkout@v1
- name: Set up dotnet
uses: actions/setup-dotnet@v3
with:
dotnet-version: ${{ env.DOTNET_SDK_VERSION }}
# - uses: actions/checkout@v1
# - name: Set up dotnet
# uses: actions/setup-dotnet@v3
# with:
# dotnet-version: ${{ env.DOTNET_SDK_VERSION }}
- run: dotnet publish src/N_m3u8DL-RE -r linux-x64 -c Release -o artifact
- run: dotnet publish src/N_m3u8DL-RE -r linux-arm64 -c Release -o artifact-arm64
# - run: dotnet publish src/N_m3u8DL-RE -r linux-x64 -c Release -o artifact
# - run: dotnet publish src/N_m3u8DL-RE -r linux-arm64 -c Release -o artifact-arm64
- name: Package [linux]
run: |
cd artifact
tar -czvf ../N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_linux-x64_${{ needs.set-date.outputs.date }}.tar.gz N_m3u8DL-RE
cd ../artifact-arm64
tar -czvf ../N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_linux-arm64_${{ needs.set-date.outputs.date }}.tar.gz N_m3u8DL-RE
# - name: Package [linux]
# run: |
# cd artifact
# tar -czvf ../N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_linux-x64_${{ needs.set-date.outputs.date }}.tar.gz N_m3u8DL-RE
# cd ../artifact-arm64
# tar -czvf ../N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_linux-arm64_${{ needs.set-date.outputs.date }}.tar.gz N_m3u8DL-RE
- name: Upload Artifact [linux-x64]
uses: actions/upload-artifact@v3.1.3
with:
name: linux-x64
path: N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_linux-x64_${{ needs.set-date.outputs.date }}.tar.gz
# - name: Upload Artifact [linux-x64]
# uses: actions/upload-artifact@v4
# with:
# name: linux-x64
# path: N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_linux-x64_${{ needs.set-date.outputs.date }}.tar.gz
- name: Upload Artifact[linux-arm64]
uses: actions/upload-artifact@v3.1.3
with:
name: linux-arm64
path: N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_linux-arm64_${{ needs.set-date.outputs.date }}.tar.gz
# - name: Upload Artifact[linux-arm64]
# uses: actions/upload-artifact@v4
# with:
# name: linux-arm64
# path: N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_linux-arm64_${{ needs.set-date.outputs.date }}.tar.gz
build-android-bionic-x64-arm64:
runs-on: windows-latest
@ -193,13 +193,13 @@ jobs:
tar -czvf ../N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_android-bionic-arm64_${{ needs.set-date.outputs.date }}.tar.gz N_m3u8DL-RE
- name: Upload Artifact [linux-bionic-x64]
uses: actions/upload-artifact@v3.1.3
uses: actions/upload-artifact@v4
with:
name: android-bionic-x64
path: N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_android-bionic-x64_${{ needs.set-date.outputs.date }}.tar.gz
- name: Upload Artifact[linux-bionic-arm64]
uses: actions/upload-artifact@v3.1.3
uses: actions/upload-artifact@v4
with:
name: android-bionic-arm64
path: N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_android-bionic-arm64_${{ needs.set-date.outputs.date }}.tar.gz
@ -221,7 +221,7 @@ jobs:
tar -czvf ../N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_linux-musl-x64_${{ needs.set-date.outputs.date }}.tar.gz N_m3u8DL-RE
- name: Upload Artifact [linux-musl-x64]
uses: actions/upload-artifact@v3.1.3
uses: actions/upload-artifact@v4
with:
name: linux-musl-x64
path: N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_linux-musl-x64_${{ needs.set-date.outputs.date }}.tar.gz
@ -249,7 +249,7 @@ jobs:
tar -czvf ../N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_linux-musl-arm64_${{ needs.set-date.outputs.date }}.tar.gz N_m3u8DL-RE
- name: Upload Artifact [linux-musl-arm64]
uses: actions/upload-artifact@v3.1.3
uses: actions/upload-artifact@v4
with:
name: linux-musl-arm64
path: N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_linux-musl-arm64_${{ needs.set-date.outputs.date }}.tar.gz
@ -276,13 +276,13 @@ jobs:
tar -czvf ../N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_osx-arm64_${{ needs.set-date.outputs.date }}.tar.gz N_m3u8DL-RE
- name: Upload Artifact [osx-x64]
uses: actions/upload-artifact@v3.1.3
uses: actions/upload-artifact@v4
with:
name: osx-x64
path: N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_osx-x64_${{ needs.set-date.outputs.date }}.tar.gz
- name: Upload Artifact[osx-arm64]
uses: actions/upload-artifact@v3.1.3
uses: actions/upload-artifact@v4
with:
name: osx-arm64
path: N_m3u8DL-RE_${{ needs.set-date.outputs.tag }}_osx-arm64_${{ needs.set-date.outputs.date }}.tar.gz
@ -293,11 +293,11 @@ jobs:
permissions:
contents: write
if: ${{ github.event.inputs.doRelease == 'true' }}
needs: [set-date,build-win-nt6_0-x86,build-win-x64-arm64,build-linux-x64-arm64,build-android-bionic-x64-arm64,build-linux-musl-x64,build-linux-musl-arm64,build-mac-x64-arm64]
needs: [set-date,build-win-nt6_0-x86,build-win-x64-arm64,build-android-bionic-x64-arm64,build-linux-musl-x64,build-linux-musl-arm64,build-mac-x64-arm64]
steps:
- name: Fetch artifacts
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
- name: Create GitHub Release
uses: ncipollo/release-action@v1
@ -307,5 +307,4 @@ jobs:
artifacts: "android-bionic-x64/*,android-bionic-arm64/*,linux-x64/*,linux-arm64/*,linux-musl-x64/*,linux-musl-arm64/*,osx-x64/*,osx-arm64/*,win-x64/*,win-arm64/*,win-NT6.0-x86/*"
draft: false
allowUpdates: true
generateReleaseNotes: true
discussionCategory: 'Announcements'
generateReleaseNotes: true

3
.gitignore vendored
View File

@ -369,3 +369,6 @@ FodyWeavers.xsd
# macOS shit
.DS_Store
artifact-arm64
test.md
build.md

View File

@ -68,7 +68,7 @@ Options:
--key KID1:KEY1 --key KID2:KEY2
对于KEY相同的情况可以直接输入 --key 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
--mp4-real-time-decryption 实时解密MP4分片 [default: False]
-R, --max-speed <SPEED> 设置限速,单位支持 Mbps 或 Kbps15M 100K

View File

@ -77,6 +77,7 @@ public static 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_useMP4Box => GetText("cmd_useMP4Box");
public static string cmd_decryptionEngine => GetText("cmd_decryptionEngine");
public static string cmd_concurrentDownload => GetText("cmd_concurrentDownload");
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 mp4decryptNotFound => GetText("mp4decryptNotFound");
public static string shakaPackagerNotFound => GetText("shakaPackagerNotFound");
public static string mp4boxNotFound => GetText("mp4boxNotFound");
public static string fixingTTML => GetText("fixingTTML");
public static string fixingTTMLmp4 => GetText("fixingTTMLmp4");
public static string fixingVTT => GetText("fixingVTT");

View File

@ -466,6 +466,12 @@ internal static class StaticText
zhTW: "解密時使用shaka-packager替代mp4decrypt",
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
(
zhCN: "设置解密时使用的第三方程序",
@ -790,6 +796,12 @@ internal static class StaticText
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"
),
["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
(
zhCN: "找不到mp4decrypt请自行下载https://www.bento4.com/downloads/",

View File

@ -177,6 +177,7 @@ public partial class MSSMoovProcessor
// widevine
else if (ProtectionSystemId.ToUpper() == "EDEF8BA9-79D6-4ACE-A3C8-27DCD51D21ED")
{
// Console.WriteLine($"WV Protection Data: {ProtectionData}");
throw new NotSupportedException();
}
}

View File

@ -17,7 +17,7 @@ namespace N_m3u8DL_RE.CommandLine;
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)")]
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> 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> 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<bool> ForceAnsiConsole = new(["--force-ansi-console"], description: ResString.cmd_forceAnsiConsole);
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),
MP4RealTimeDecryption = bindingContext.ParseResult.GetValueForOption(MP4RealTimeDecryption),
UseShakaPackager = bindingContext.ParseResult.GetValueForOption(UseShakaPackager),
UseMP4Box = bindingContext.ParseResult.GetValueForOption(UseMP4Box),
DecryptionEngine = bindingContext.ParseResult.GetValueForOption(DecryptionEngine),
DecryptionBinaryPath = bindingContext.ParseResult.GetValueForOption(DecryptionBinaryPath),
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,
BinaryMerge, UseFFmpegConcatDemuxer, DelAfterDone, NoDateInfo, NoLog, WriteMetaJson, AppendUrlParams, ConcurrentDownload, Headers, /**SavePattern,**/ SubOnly, SubtitleFormat, AutoSubtitleFix,
FFmpegBinaryPath,
LogLevel, UILanguage, UrlProcessorArgs, Keys, KeyTextFile, DecryptionEngine, DecryptionBinaryPath, UseShakaPackager, MP4RealTimeDecryption,
LogLevel, UILanguage, UrlProcessorArgs, Keys, KeyTextFile, DecryptionEngine, DecryptionBinaryPath, UseShakaPackager, UseMP4Box, MP4RealTimeDecryption,
MaxSpeed,
MuxAfterDone,
CustomHLSMethod, CustomHLSKey, CustomHLSIv, UseSystemProxy, CustomProxy, CustomRange, TaskStartAt,

View File

@ -144,6 +144,10 @@ internal class MyOption
/// <summary>
/// See: <see cref="CommandInvoker.DecryptionEngine"/>.
/// </summary>
public bool UseMP4Box { get; set; }
/// <summary>
/// See: <see cref="CommandInvoker.DecryptionEngine"/>.
/// </summary>
public DecryptEngine DecryptionEngine { get; set; }
/// <summary>
/// See: <see cref="CommandInvoker.MuxAfterDone"/>.

View File

@ -4,5 +4,6 @@ internal enum DecryptEngine
{
MP4DECRYPT,
SHAKA_PACKAGER,
MP4BOX,
FFMPEG,
}

View File

@ -126,6 +126,10 @@ internal class Program
{
option.DecryptionEngine = DecryptEngine.SHAKA_PACKAGER;
}
if (option.UseMP4Box)
{
option.DecryptionEngine = DecryptEngine.MP4BOX;
}
// LivePipeMux开启时 LiveRealTimeMerge必须开启
if (option is { LivePipeMux: true, LiveRealTimeMerge: false })
@ -184,6 +188,14 @@ internal class Program
Logger.Extra($"mp4decrypt => {option.DecryptionBinaryPath}");
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:
default:
option.DecryptionBinaryPath = option.FFmpegBinaryPath;

View File

@ -51,7 +51,7 @@ internal static partial class MP4DecryptUtil
// shakaPackager/ffmpeg 无法单独解密init文件
if (source.EndsWith("_init.mp4") && decryptEngine != DecryptEngine.MP4DECRYPT) return false;
string cmd;
string cmd = "";
var tmpFile = "";
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}\" " +
$"--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)
{