You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
6.1 KiB
174 lines
6.1 KiB
using McMaster.Extensions.CommandLineUtils;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using VGMToolbox.format;
|
|
|
|
namespace UsmToolkit
|
|
{
|
|
[Command(Description = "Extract audio and video")]
|
|
public class ExtractCommand
|
|
{
|
|
[Required]
|
|
[FileOrDirectoryExists]
|
|
[Argument(0, Description = "File or folder containing usm files")]
|
|
public string InputPath { get; set; }
|
|
|
|
protected int OnExecute(CommandLineApplication app)
|
|
{
|
|
FileAttributes attr = File.GetAttributes(InputPath);
|
|
if (attr.HasFlag(FileAttributes.Directory))
|
|
{
|
|
foreach (var file in Directory.GetFiles(InputPath, "*.usm"))
|
|
Process(file);
|
|
}
|
|
else
|
|
Process(InputPath);
|
|
|
|
return 0;
|
|
}
|
|
|
|
private void Process(string fileName)
|
|
{
|
|
Console.WriteLine($"File: {fileName}");
|
|
var usmStream = new CriUsmStream(fileName);
|
|
|
|
Console.WriteLine("Demuxing...");
|
|
usmStream.DemultiplexStreams(new MpegStream.DemuxOptionsStruct()
|
|
{
|
|
AddHeader = false,
|
|
AddPlaybackHacks = false,
|
|
ExtractAudio = true,
|
|
ExtractVideo = true,
|
|
SplitAudioStreams = false
|
|
});
|
|
}
|
|
}
|
|
|
|
[Command(Description = "Convert according to the parameters in config.json")]
|
|
public class ConvertCommand
|
|
{
|
|
[Required]
|
|
[FileOrDirectoryExists]
|
|
[Argument(0, Description = "File or folder containing usm files")]
|
|
public string InputPath { get; set; }
|
|
|
|
[Option(CommandOptionType.SingleValue, Description = "Specify output directory", ShortName = "o", LongName = "output-dir")]
|
|
public string OutputDir { get; set; }
|
|
|
|
[Option(CommandOptionType.NoValue, Description = "Remove temporary m2v and audio after converting", ShortName = "c", LongName = "clean")]
|
|
public bool CleanTempFiles { get; set; }
|
|
|
|
protected int OnExecute(CommandLineApplication app)
|
|
{
|
|
FileAttributes attr = File.GetAttributes(InputPath);
|
|
if (attr.HasFlag(FileAttributes.Directory))
|
|
{
|
|
foreach (var file in Directory.GetFiles(InputPath, "*.usm"))
|
|
Process(file);
|
|
}
|
|
else
|
|
Process(InputPath);
|
|
|
|
return 0;
|
|
}
|
|
|
|
private void Process(string fileName)
|
|
{
|
|
Console.WriteLine($"File: {fileName}");
|
|
var usmStream = new CriUsmStream(fileName);
|
|
|
|
Console.WriteLine("Demuxing...");
|
|
usmStream.DemultiplexStreams(new MpegStream.DemuxOptionsStruct()
|
|
{
|
|
AddHeader = false,
|
|
AddPlaybackHacks = false,
|
|
ExtractAudio = true,
|
|
ExtractVideo = true,
|
|
SplitAudioStreams = false
|
|
});
|
|
|
|
if (!string.IsNullOrEmpty(OutputDir) && !Directory.Exists(OutputDir))
|
|
Directory.CreateDirectory(OutputDir);
|
|
|
|
JoinOutputFile(usmStream);
|
|
}
|
|
|
|
private void JoinOutputFile(CriUsmStream usmStream)
|
|
{
|
|
if (!File.Exists("config.json"))
|
|
{
|
|
Console.WriteLine("ERROR: config.json not found!");
|
|
return;
|
|
}
|
|
|
|
var audioFormat = usmStream.FinalAudioExtension;
|
|
var pureFileName = Path.GetFileNameWithoutExtension(usmStream.FilePath);
|
|
|
|
if (audioFormat == ".adx")
|
|
{
|
|
//ffmpeg can not handle .adx from 0.2 for whatever reason
|
|
//need vgmstream to format that to wav
|
|
if (!Directory.Exists("vgmstream"))
|
|
{
|
|
Console.WriteLine("ERROR: vgmstream folder not found!");
|
|
return;
|
|
}
|
|
|
|
Console.WriteLine("adx audio detected, convert to wav...");
|
|
Helpers.ExecuteProcess("vgmstream/test.exe", $"\"{Path.ChangeExtension(usmStream.FilePath, usmStream.FinalAudioExtension)}\" -o \"{Path.ChangeExtension(usmStream.FilePath, "wav")}\"");
|
|
|
|
usmStream.FinalAudioExtension = ".wav";
|
|
}
|
|
|
|
Helpers.ExecuteProcess("ffmpeg", Helpers.CreateFFmpegParameters(usmStream, pureFileName, OutputDir));
|
|
|
|
if (CleanTempFiles)
|
|
{
|
|
Console.WriteLine($"Cleaning up temporary files from {pureFileName}");
|
|
|
|
File.Delete(Path.ChangeExtension(usmStream.FilePath, "wav"));
|
|
File.Delete(Path.ChangeExtension(usmStream.FilePath, "adx"));
|
|
File.Delete(Path.ChangeExtension(usmStream.FilePath, "hca"));
|
|
File.Delete(Path.ChangeExtension(usmStream.FilePath, "m2v"));
|
|
}
|
|
}
|
|
}
|
|
|
|
[Command(Description = "Setup ffmpeg and vgmstream needed for conversion")]
|
|
public class GetDependenciesCommand
|
|
{
|
|
protected int OnExecute(CommandLineApplication app)
|
|
{
|
|
DepsConfig conf = JsonConvert.DeserializeObject<DepsConfig>(File.ReadAllText("deps.json"));
|
|
WebClient client = new WebClient();
|
|
|
|
Console.WriteLine($"Downloading ffmpeg from {conf.FFmpeg}");
|
|
client.DownloadFile(conf.FFmpeg, "ffmpeg.zip");
|
|
|
|
Console.WriteLine($"Extracting ffmpeg...");
|
|
using (ZipArchive archive = ZipFile.OpenRead("ffmpeg.zip"))
|
|
{
|
|
var ent = archive.Entries.FirstOrDefault(x => x.Name == "ffmpeg.exe");
|
|
if (ent != null)
|
|
{
|
|
ent.ExtractToFile("ffmpeg.exe", true);
|
|
}
|
|
}
|
|
File.Delete("ffmpeg.zip");
|
|
|
|
Console.WriteLine($"Downloading vgmstream from {conf.Vgmstream}");
|
|
client.DownloadFile(conf.Vgmstream, "vgmstream.zip");
|
|
|
|
Console.WriteLine("Extracting vgmstream...");
|
|
ZipFile.ExtractToDirectory("vgmstream.zip", "vgmstream", true);
|
|
File.Delete("vgmstream.zip");
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|