using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; namespace ffmpeg_decrypt { public partial class Form1 : Form { public Form1() { InitializeComponent(); qualityCombo.SelectedIndex = 1; // value == 80 statuslbl.Text = ""; decryptRb.Checked = true; } private void inpbutton_Click(object sender, EventArgs e) { using var ofd = new OpenFileDialog { Filter = "Audible Audio Files|*.aax", Title = "Select an Audible Audio File", FileName = "" }; if (ofd.ShowDialog() == DialogResult.OK) { inputdisplay.Text = ofd.FileName; outputdisplay.Text = Path.GetDirectoryName(ofd.FileName); convertbutton.Enabled = true; } } private void outpbutton_Click(object sender, EventArgs e) { using var fbd = new FolderBrowserDialog(); if (fbd.ShowDialog() == DialogResult.OK && !string.IsNullOrWhiteSpace(fbd.SelectedPath)) outputdisplay.Text = fbd.SelectedPath; } private async void convertbutton_Click(object sender, EventArgs e) { //var sw = Stopwatch.StartNew(); // disable UI inputPnl.Enabled = false; statuslbl.Text = "Getting File Hash..."; var checksum = await RCrack.GetChecksum(inputdisplay.Text); statuslbl.Text = "Cracking Activation Bytes..."; var activation_bytes = await RCrack.GetActivationBytes(checksum); statuslbl.Text = "Converting File..."; var encodeTo = decryptRb.Checked ? EncodeTo.DecryptOnly : rmp3.Checked ? EncodeTo.Mp3 : raac.Checked ? EncodeTo.M4b : rflac.Checked ? EncodeTo.Flac : throw new NotImplementedException(); await decryptAndSaveFile(activation_bytes, inputdisplay.Text, outputdisplay.Text, txtConsole, encodeTo, int.Parse(qualityCombo.Text)); // re-enable UI inputPnl.Enabled = true; //sw.Stop(); //var total = (int)sw.Elapsed.TotalSeconds; statuslbl.Text = "Conversion Complete!"; } // ProcessStartInfo.Arguments: use Escaper.EscapeArguments instead of .SurroundWithQuotes() // see also: https://stackoverflow.com/questions/4291912/process-start-how-to-get-the-output // top 2 answers show: easy, sync, async enum EncodeTo { /// Decrypt only. Retain original encoding DecryptOnly, /// LAME MP3 Mp3, /// M4B AAC M4b, /// FLAC HD Flac } private static async Task decryptAndSaveFile(string activation_bytes, string inputPath, string outputPath, TextBoxBase debugWindow, EncodeTo encodeTo, int encodeQuality = 80) { Resources.Extract("ffmpeg.exe"); var fileBase = Path.Combine(outputPath, Path.GetFileNameWithoutExtension(inputPath)); string arguments; // only decrypt. no re-encoding if (encodeTo == EncodeTo.DecryptOnly) { var fileout = fileBase + ".m4b"; arguments = $"-activation_bytes {activation_bytes} -i {inputPath.SurroundWithQuotes()} -vn -c:a copy {fileout.SurroundWithQuotes()}"; } // re-encode. encoding will be determined by file extension else // if (convertRb.Checked) { var fileout = fileBase + "." + encodeTo.ToString().ToLower(); arguments = $"-y -activation_bytes {activation_bytes} -i {inputPath.SurroundWithQuotes()} -ab {encodeQuality} -map_metadata 0 -id3v2_version 3 -vn {fileout.SurroundWithQuotes()}"; } // nothing in stdout. progress/debug info is in stderr var startInfo = new ProcessStartInfo { FileName = Path.Combine(Resources.resdir, "ffmpeg.exe"), Arguments = arguments, CreateNoWindow = true, RedirectStandardError = true, UseShellExecute = false, WorkingDirectory = Directory.GetCurrentDirectory() }; using var ffm = new Process { StartInfo = startInfo, EnableRaisingEvents = true }; ffm.ErrorDataReceived += (s, ea) => debugWindow.UIThread(() => debugWindow.AppendText($"DEBUG: {ea.Data}\r\n")); ffm.Start(); ffm.BeginErrorReadLine(); await Task.Run(() => ffm.WaitForExit()); ffm.Close(); } private void decryptConvertRb_CheckedChanged(object sender, EventArgs e) => convertGb.Enabled = convertRb.Checked; } }