Skip to content

Commit

Permalink
feat(api): add --key parameter for demuxing
Browse files Browse the repository at this point in the history
  • Loading branch information
ToaHartor committed Sep 28, 2024
1 parent eefd56e commit 475b632
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 2 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ Several options are available for most of the commands :
- `--audio-format` and `--video-format` can be used to select codecs. If at least one option is chosen, **the merging engine is automatically changed to FFMPEG**.
- `--audio-lang` allow to specify audio track language in the output, allowed values are `[chi,eng,jpn,kor]`

For demuxing, a key can be supplied to decrypt the USM file using either the parameter `--key <hex or number>` or `-b <4 lower bytes of key> -a <4 higher bytes of key>`.

Maintenance commands and options:

- `update` retrieves the latest `versions.json` file from the repository and checks if a new version has to be downloaded. It can take several optional parameters as follows :
Expand Down
9 changes: 9 additions & 0 deletions src/Commands/DemuxCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public DemuxCommand()

CliOptions.Output.AddAlias("-o");
AddOption(CliOptions.Output);
AddOption(CliOptions.HexKey);
AddOption(CliOptions.Key1);
AddOption(CliOptions.Key2);
CliOptions.Subs.AddAlias("--subtitles");
Expand All @@ -43,6 +44,7 @@ public DemuxCommand()
DemuxArgsOptionsBinder demuxArgsOptions = new DemuxArgsOptionsBinder(
demuxInputArg,
CliOptions.Output,
CliOptions.HexKey,
CliOptions.Key1,
CliOptions.Key2,
CliOptions.MkvEngine,
Expand All @@ -65,13 +67,20 @@ private static void Execute(DemuxArgsOptions demuxArgsOptions)
// Check given arguments and options
if (!input.Exists)
throw new ArgumentNullException($"Input path does not exist: {input.FullName}");

DirectoryInfo output = demuxArgsOptions.output;
if (!output.Exists)
output.Create();

byte[] key1 = demuxArgsOptions.key1 ?? Array.Empty<byte>();
byte[] key2 = demuxArgsOptions.key2 ?? Array.Empty<byte>();

if (demuxArgsOptions.hexKey != null)
{
key1 = demuxArgsOptions.hexKey[..4];
key2 = demuxArgsOptions.hexKey[4..];
}

bool merge = demuxArgsOptions.merge;
bool includeSubs = demuxArgsOptions.subs;
bool noCleanup = demuxArgsOptions.noCleanup;
Expand Down
4 changes: 2 additions & 2 deletions src/Demuxer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,9 @@ DirectoryInfo output
Dictionary<string, List<string>> filePaths = usmFile.Demux(true, true, output.FullName); // TODO: Return file list for easier parsing

if (!filePaths.TryGetValue("hca", out List<string> hcaPaths))
throw new Exception("No HCA files could be demuxed...");
Console.WriteLine("No HCA files have been demuxed...");

Task[] decodingTasks = new Task[hcaPaths.Count];
Task[] decodingTasks = new Task[(hcaPaths?.Count) ?? 0];
for (int i = 0; i < decodingTasks.Length; i++)
{
int j = i;
Expand Down
4 changes: 4 additions & 0 deletions src/Parameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ internal sealed class DemuxArgsOptions
{
public required FileSystemInfo input;
public required DirectoryInfo output;
public byte[]? hexKey;
public byte[]? key1;
public byte[]? key2;
public bool merge;
Expand All @@ -21,6 +22,7 @@ internal sealed class DemuxArgsOptions
internal sealed class DemuxArgsOptionsBinder(
Argument<FileSystemInfo> inputArg,
Option<DirectoryInfo> outputOption,
Option<byte[]> hexKeyOption,
Option<byte[]> key1Option,
Option<byte[]> key2Option,
Option<string> mkvEngineOption,
Expand All @@ -34,6 +36,7 @@ Option<string> audioLangOption
{
private Argument<FileSystemInfo> InputArg { get; } = inputArg;
private Option<DirectoryInfo> OutputOption { get; } = outputOption;
private Option<byte[]> HexKeyOption { get; } = hexKeyOption;
private Option<byte[]> Key1Option { get; } = key1Option;
private Option<byte[]> Key2Option { get; } = key2Option;
private Option<string> MkvEngineOption { get; } = mkvEngineOption;
Expand All @@ -51,6 +54,7 @@ protected override DemuxArgsOptions GetBoundValue(BindingContext bindingContext)
output =
bindingContext.ParseResult.GetValueForOption(OutputOption)
?? new DirectoryInfo("./output"),
hexKey = bindingContext.ParseResult.GetValueForOption(HexKeyOption),
key1 = bindingContext.ParseResult.GetValueForOption(Key1Option),
key2 = bindingContext.ParseResult.GetValueForOption(Key2Option),
subs = bindingContext.ParseResult.GetValueForOption(SubsOption),
Expand Down
26 changes: 26 additions & 0 deletions src/Utils/CliOptions.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Buffers.Binary;
using System.CommandLine;

namespace GICutscenes;
Expand All @@ -10,6 +11,31 @@ public static class CliOptions
getDefaultValue: () => new DirectoryInfo("./output")
);

public static Option<byte[]> HexKey = new Option<byte[]>(
name: "--key",
description: "USM encryption key (hexadecimal and number format are supported). Overrides options '-a' and '-b'",
parseArgument: result =>
{
string strKey = result.Tokens.Single().Value;
// If number only || If hex (0x before or letters A-F)
if (
ulong.TryParse(strKey, out ulong numKey)
|| ulong.TryParse(
strKey.StartsWith("0x") ? strKey.Substring(2) : strKey,
System.Globalization.NumberStyles.HexNumber,
null,
out numKey
)
)
{
byte[] byteKey = new byte[8];
BitConverter.GetBytes(numKey).CopyTo(byteKey, 0);
return byteKey;
}
throw new ArgumentException("Argument --key <key> does not have the right format");
}
);

public static Option<byte[]> Key1 = new Option<byte[]>(
name: "-a",
description: "4 lower bytes of the key (hex format)",
Expand Down

0 comments on commit 475b632

Please sign in to comment.