From 05f25a88c6ec66faab1367daf565b30761897b71 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Sun, 8 May 2022 11:08:23 -0600 Subject: [PATCH 1/9] Fix temp file reuse/cleanup. Add retain aax option. --- AaxDecrypter/AaxcDownloadConvertBase.cs | 6 +-- AaxDecrypter/AaxcDownloadMultiConverter.cs | 24 ++++------ AaxDecrypter/AaxcDownloadSingleConverter.cs | 13 ++--- AaxDecrypter/AudiobookDownloadBase.cs | 48 ++++++++++++++----- ...{DownloadLicense.cs => DownloadOptions.cs} | 5 +- .../UnencryptedAudiobookDownloader.cs | 2 +- AppScaffolding/LibationScaffolding.cs | 3 ++ FileLiberator/AudioFileStorageExt.cs | 2 +- FileLiberator/DownloadDecryptBook.cs | 23 +++++---- FileManager/FileNamingTemplate.cs | 4 +- FileManager/FileUtility.cs | 4 +- LibationFileManager/Configuration.cs | 7 +++ LibationFileManager/Templates.cs | 4 +- 13 files changed, 90 insertions(+), 55 deletions(-) rename AaxDecrypter/{DownloadLicense.cs => DownloadOptions.cs} (82%) diff --git a/AaxDecrypter/AaxcDownloadConvertBase.cs b/AaxDecrypter/AaxcDownloadConvertBase.cs index 4784be37..1567d8b3 100644 --- a/AaxDecrypter/AaxcDownloadConvertBase.cs +++ b/AaxDecrypter/AaxcDownloadConvertBase.cs @@ -10,7 +10,7 @@ namespace AaxDecrypter protected AaxFile AaxFile; - protected AaxcDownloadConvertBase(string outFileName, string cacheDirectory, DownloadLicense dlLic) + protected AaxcDownloadConvertBase(string outFileName, string cacheDirectory, DownloadOptions dlLic) : base(outFileName, cacheDirectory, dlLic) { } /// Setting cover art by this method will insert the art into the audiobook metadata @@ -46,7 +46,7 @@ namespace AaxDecrypter OnDecryptProgressUpdate(zeroProgress); - AaxFile.SetDecryptionKey(DownloadLicense.AudibleKey, DownloadLicense.AudibleIV); + AaxFile.SetDecryptionKey(DownloadOptions.AudibleKey, DownloadOptions.AudibleIV); return zeroProgress; } @@ -68,7 +68,7 @@ namespace AaxDecrypter if (double.IsNormal(estTimeRemaining)) OnDecryptTimeRemaining(TimeSpan.FromSeconds(estTimeRemaining)); - var progressPercent = e.ProcessPosition.TotalSeconds / duration.TotalSeconds; + var progressPercent = (e.ProcessPosition / e.TotalDuration); OnDecryptProgressUpdate( new DownloadProgress diff --git a/AaxDecrypter/AaxcDownloadMultiConverter.cs b/AaxDecrypter/AaxcDownloadMultiConverter.cs index ba4dc68c..82e8d047 100644 --- a/AaxDecrypter/AaxcDownloadMultiConverter.cs +++ b/AaxDecrypter/AaxcDownloadMultiConverter.cs @@ -18,13 +18,13 @@ namespace AaxDecrypter private static TimeSpan minChapterLength { get; } = TimeSpan.FromSeconds(3); private List multiPartFilePaths { get; } = new List(); - public AaxcDownloadMultiConverter(string outFileName, string cacheDirectory, DownloadLicense dlLic, + public AaxcDownloadMultiConverter(string outFileName, string cacheDirectory, DownloadOptions dlLic, Func multipartFileNameCallback = null) : base(outFileName, cacheDirectory, dlLic) { Steps = new StepSequence { - Name = "Download and Convert Aaxc To " + DownloadLicense.OutputFormat, + Name = "Download and Convert Aaxc To " + DownloadOptions.OutputFormat, ["Step 1: Get Aaxc Metadata"] = Step_GetMetadata, ["Step 2: Download Decrypted Audiobook"] = Step_DownloadAudiobookAsMultipleFilesPerChapter, @@ -61,10 +61,10 @@ That naming may not be desirable for everyone, but it's an easy change to instea { var zeroProgress = Step_DownloadAudiobook_Start(); - var chapters = DownloadLicense.ChapterInfo.Chapters.ToList(); + var chapters = DownloadOptions.ChapterInfo.Chapters.ToList(); // Ensure split files are at least minChapterLength in duration. - var splitChapters = new ChapterInfo(DownloadLicense.ChapterInfo.StartOffset); + var splitChapters = new ChapterInfo(DownloadOptions.ChapterInfo.StartOffset); var runningTotal = TimeSpan.Zero; string title = ""; @@ -89,7 +89,7 @@ That naming may not be desirable for everyone, but it's an easy change to instea ConversionResult result; AaxFile.ConversionProgressUpdate += AaxFile_ConversionProgressUpdate; - if (DownloadLicense.OutputFormat == OutputFormat.M4b) + if (DownloadOptions.OutputFormat == OutputFormat.M4b) result = ConvertToMultiMp4a(splitChapters); else result = ConvertToMultiMp3(splitChapters); @@ -97,13 +97,7 @@ That naming may not be desirable for everyone, but it's an easy change to instea Step_DownloadAudiobook_End(zeroProgress); - var success = result == ConversionResult.NoErrorsDetected; - - if (success) - foreach (var path in multiPartFilePaths) - OnFileCreated(path); - - return success; + return result == ConversionResult.NoErrorsDetected; } private ConversionResult ConvertToMultiMp4a(ChapterInfo splitChapters) @@ -111,7 +105,7 @@ That naming may not be desirable for everyone, but it's an easy change to instea var chapterCount = 0; return AaxFile.ConvertToMultiMp4a(splitChapters, newSplitCallback => createOutputFileStream(++chapterCount, splitChapters, newSplitCallback), - DownloadLicense.TrimOutputToChapterLength); + DownloadOptions.TrimOutputToChapterLength); } private ConversionResult ConvertToMultiMp3(ChapterInfo splitChapters) @@ -121,7 +115,7 @@ That naming may not be desirable for everyone, but it's an easy change to instea { createOutputFileStream(++chapterCount, splitChapters, newSplitCallback); ((NAudio.Lame.LameConfig)newSplitCallback.UserState).ID3.Track = chapterCount.ToString(); - }, null, DownloadLicense.TrimOutputToChapterLength); + }, null, DownloadOptions.TrimOutputToChapterLength); } private void createOutputFileStream(int currentChapter, ChapterInfo splitChapters, NewSplitCallback newSplitCallback) @@ -140,6 +134,8 @@ That naming may not be desirable for everyone, but it's an easy change to instea FileUtility.SaferDelete(fileName); newSplitCallback.OutputFile = File.Open(fileName, FileMode.OpenOrCreate); + + OnFileCreated(fileName); } } } diff --git a/AaxDecrypter/AaxcDownloadSingleConverter.cs b/AaxDecrypter/AaxcDownloadSingleConverter.cs index 0592d108..e9492d20 100644 --- a/AaxDecrypter/AaxcDownloadSingleConverter.cs +++ b/AaxDecrypter/AaxcDownloadSingleConverter.cs @@ -11,12 +11,12 @@ namespace AaxDecrypter { protected override StepSequence Steps { get; } - public AaxcDownloadSingleConverter(string outFileName, string cacheDirectory, DownloadLicense dlLic) + public AaxcDownloadSingleConverter(string outFileName, string cacheDirectory, DownloadOptions dlLic) : base(outFileName, cacheDirectory, dlLic) { Steps = new StepSequence { - Name = "Download and Convert Aaxc To " + DownloadLicense.OutputFormat, + Name = "Download and Convert Aaxc To " + DownloadOptions.OutputFormat, ["Step 1: Get Aaxc Metadata"] = Step_GetMetadata, ["Step 2: Download Decrypted Audiobook"] = Step_DownloadAudiobookAsSingleFile, @@ -32,15 +32,16 @@ namespace AaxDecrypter FileUtility.SaferDelete(OutputFileName); var outputFile = File.Open(OutputFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite); + OnFileCreated(OutputFileName); AaxFile.ConversionProgressUpdate += AaxFile_ConversionProgressUpdate; var decryptionResult - = DownloadLicense.OutputFormat == OutputFormat.M4b - ? AaxFile.ConvertToMp4a(outputFile, DownloadLicense.ChapterInfo, DownloadLicense.TrimOutputToChapterLength) - : AaxFile.ConvertToMp3(outputFile, null, DownloadLicense.ChapterInfo, DownloadLicense.TrimOutputToChapterLength); + = DownloadOptions.OutputFormat == OutputFormat.M4b + ? AaxFile.ConvertToMp4a(outputFile, DownloadOptions.ChapterInfo, DownloadOptions.TrimOutputToChapterLength) + : AaxFile.ConvertToMp3(outputFile, null, DownloadOptions.ChapterInfo, DownloadOptions.TrimOutputToChapterLength); AaxFile.ConversionProgressUpdate -= AaxFile_ConversionProgressUpdate; - DownloadLicense.ChapterInfo = AaxFile.Chapters; + DownloadOptions.ChapterInfo = AaxFile.Chapters; Step_DownloadAudiobook_End(zeroProgress); diff --git a/AaxDecrypter/AudiobookDownloadBase.cs b/AaxDecrypter/AudiobookDownloadBase.cs index 80ab189d..0de90a27 100644 --- a/AaxDecrypter/AudiobookDownloadBase.cs +++ b/AaxDecrypter/AudiobookDownloadBase.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.IO; using Dinah.Core; using Dinah.Core.Net.Http; @@ -20,8 +21,9 @@ namespace AaxDecrypter public event EventHandler FileCreated; protected bool IsCanceled { get; set; } + protected string OutputFileName { get; private set; } - protected DownloadLicense DownloadLicense { get; } + protected DownloadOptions DownloadOptions { get; } protected NetworkFileStream InputFileStream => (nfsPersister ??= OpenNetworkFileStream()).NetworkFileStream; // Don't give the property a 'set'. This should have to be an obvious choice; not accidental @@ -31,9 +33,9 @@ namespace AaxDecrypter private NetworkFileStreamPersister nfsPersister; private string jsonDownloadState { get; } - private string tempFile => Path.ChangeExtension(jsonDownloadState, ".tmp"); + public string TempFilePath { get; } - protected AudiobookDownloadBase(string outFileName, string cacheDirectory, DownloadLicense dlLic) + protected AudiobookDownloadBase(string outFileName, string cacheDirectory, DownloadOptions dlLic) { OutputFileName = ArgumentValidator.EnsureNotNullOrWhiteSpace(outFileName, nameof(outFileName)); @@ -43,9 +45,11 @@ namespace AaxDecrypter if (!Directory.Exists(cacheDirectory)) throw new DirectoryNotFoundException($"Directory does not exist: {nameof(cacheDirectory)}"); - jsonDownloadState = Path.Combine(cacheDirectory, Path.ChangeExtension(OutputFileName, ".json")); - DownloadLicense = ArgumentValidator.EnsureNotNull(dlLic, nameof(dlLic)); + jsonDownloadState = Path.Combine(cacheDirectory, Path.GetFileName(Path.ChangeExtension(OutputFileName, ".json"))); + TempFilePath = Path.ChangeExtension(jsonDownloadState, ".tmp"); + + DownloadOptions = ArgumentValidator.EnsureNotNull(dlLic, nameof(dlLic)); // delete file after validation is complete FileUtility.SaferDelete(OutputFileName); @@ -99,7 +103,7 @@ namespace AaxDecrypter { var path = Path.ChangeExtension(OutputFileName, ".cue"); path = FileUtility.GetValidFilename(path); - File.WriteAllText(path, Cue.CreateContents(Path.GetFileName(OutputFileName), DownloadLicense.ChapterInfo)); + File.WriteAllText(path, Cue.CreateContents(Path.GetFileName(OutputFileName), DownloadOptions.ChapterInfo)); OnFileCreated(path); } catch (Exception ex) @@ -111,9 +115,27 @@ namespace AaxDecrypter protected bool Step_Cleanup() { - FileUtility.SaferDelete(jsonDownloadState); - FileUtility.SaferDelete(tempFile); - return !IsCanceled; + bool success = !IsCanceled; + if (success) + { + FileUtility.SaferDelete(jsonDownloadState); + + if (DownloadOptions.RetainEncryptedFile) + { + string aaxPath = Path.ChangeExtension(TempFilePath, ".aax"); + FileUtility.SaferMove(TempFilePath, aaxPath); + OnFileCreated(aaxPath); + } + else + FileUtility.SaferDelete(TempFilePath); + } + else + { + FileUtility.SaferDelete(OutputFileName); + } + + + return success; } private NetworkFileStreamPersister OpenNetworkFileStream() @@ -126,13 +148,13 @@ namespace AaxDecrypter var nfsp = new NetworkFileStreamPersister(jsonDownloadState); // If More than ~1 hour has elapsed since getting the download url, it will expire. // The new url will be to the same file. - nfsp.NetworkFileStream.SetUriForSameFile(new Uri(DownloadLicense.DownloadUrl)); + nfsp.NetworkFileStream.SetUriForSameFile(new Uri(DownloadOptions.DownloadUrl)); return nfsp; } catch { FileUtility.SaferDelete(jsonDownloadState); - FileUtility.SaferDelete(tempFile); + FileUtility.SaferDelete(TempFilePath); return NewNetworkFilePersister(); } } @@ -141,10 +163,10 @@ namespace AaxDecrypter { var headers = new System.Net.WebHeaderCollection { - { "User-Agent", DownloadLicense.UserAgent } + { "User-Agent", DownloadOptions.UserAgent } }; - var networkFileStream = new NetworkFileStream(tempFile, new Uri(DownloadLicense.DownloadUrl), 0, headers); + var networkFileStream = new NetworkFileStream(TempFilePath, new Uri(DownloadOptions.DownloadUrl), 0, headers); return new NetworkFileStreamPersister(networkFileStream, jsonDownloadState); } } diff --git a/AaxDecrypter/DownloadLicense.cs b/AaxDecrypter/DownloadOptions.cs similarity index 82% rename from AaxDecrypter/DownloadLicense.cs rename to AaxDecrypter/DownloadOptions.cs index 51b69c71..6105b1ed 100644 --- a/AaxDecrypter/DownloadLicense.cs +++ b/AaxDecrypter/DownloadOptions.cs @@ -3,7 +3,7 @@ using Dinah.Core; namespace AaxDecrypter { - public class DownloadLicense + public class DownloadOptions { public string DownloadUrl { get; } public string UserAgent { get; } @@ -11,9 +11,10 @@ namespace AaxDecrypter public string AudibleIV { get; init; } public OutputFormat OutputFormat { get; init; } public bool TrimOutputToChapterLength { get; init; } + public bool RetainEncryptedFile { get; init; } public ChapterInfo ChapterInfo { get; set; } - public DownloadLicense(string downloadUrl, string userAgent) + public DownloadOptions(string downloadUrl, string userAgent) { DownloadUrl = ArgumentValidator.EnsureNotNullOrEmpty(downloadUrl, nameof(downloadUrl)); UserAgent = ArgumentValidator.EnsureNotNullOrEmpty(userAgent, nameof(userAgent)); diff --git a/AaxDecrypter/UnencryptedAudiobookDownloader.cs b/AaxDecrypter/UnencryptedAudiobookDownloader.cs index 108a662f..885e839b 100644 --- a/AaxDecrypter/UnencryptedAudiobookDownloader.cs +++ b/AaxDecrypter/UnencryptedAudiobookDownloader.cs @@ -10,7 +10,7 @@ namespace AaxDecrypter { protected override StepSequence Steps { get; } - public UnencryptedAudiobookDownloader(string outFileName, string cacheDirectory, DownloadLicense dlLic) + public UnencryptedAudiobookDownloader(string outFileName, string cacheDirectory, DownloadOptions dlLic) : base(outFileName, cacheDirectory, dlLic) { Steps = new StepSequence diff --git a/AppScaffolding/LibationScaffolding.cs b/AppScaffolding/LibationScaffolding.cs index 2ce6611b..1317a097 100644 --- a/AppScaffolding/LibationScaffolding.cs +++ b/AppScaffolding/LibationScaffolding.cs @@ -83,6 +83,9 @@ namespace AppScaffolding if (!config.Exists(nameof(config.StripAudibleBrandAudio))) config.StripAudibleBrandAudio = false; + + if (!config.Exists(nameof(config.RetainAaxFile))) + config.RetainAaxFile = false; if (!config.Exists(nameof(config.FolderTemplate))) config.FolderTemplate = Templates.Folder.DefaultTemplate; diff --git a/FileLiberator/AudioFileStorageExt.cs b/FileLiberator/AudioFileStorageExt.cs index a58bf648..049efaed 100644 --- a/FileLiberator/AudioFileStorageExt.cs +++ b/FileLiberator/AudioFileStorageExt.cs @@ -39,7 +39,7 @@ namespace FileLiberator /// File name: final file name. /// public static string GetInProgressFilename(this AudioFileStorage _, LibraryBook libraryBook, string extension) - => Templates.File.GetFilename(libraryBook.ToDto(), AudibleFileStorage.DecryptInProgressDirectory, extension); + => Templates.File.GetFilename(libraryBook.ToDto(), AudibleFileStorage.DecryptInProgressDirectory, extension, returnFirstExisting: true); /// /// PDF: audio file does not exist diff --git a/FileLiberator/DownloadDecryptBook.cs b/FileLiberator/DownloadDecryptBook.cs index 339a2c4b..654936f8 100644 --- a/FileLiberator/DownloadDecryptBook.cs +++ b/FileLiberator/DownloadDecryptBook.cs @@ -61,7 +61,12 @@ namespace FileLiberator // decrypt failed if (!success) + { + foreach (var tmpFile in entries) + FileUtility.SaferDelete(tmpFile.Path); + return new StatusHandler { "Decrypt failed" }; + } // moves new files from temp dir to final dest var movedAudioFile = moveFilesToBooksDir(libraryBook, entries); @@ -92,7 +97,7 @@ namespace FileLiberator var api = await libraryBook.GetApiAsync(); var contentLic = await api.GetDownloadLicenseAsync(libraryBook.Book.AudibleProductId); - var audiobookDlLic = BuildDownloadLicense(config, contentLic); + var audiobookDlLic = BuildDownloadOptions(config, contentLic); var outFileName = AudibleFileStorage.Audio.GetInProgressFilename(libraryBook, audiobookDlLic.OutputFormat.ToString().ToLower()); var cacheDir = AudibleFileStorage.DownloadsInProgressDirectory; @@ -132,28 +137,28 @@ namespace FileLiberator } } - private static DownloadLicense BuildDownloadLicense(Configuration config, AudibleApi.Common.ContentLicense contentLic) + private static DownloadOptions BuildDownloadOptions(Configuration config, AudibleApi.Common.ContentLicense contentLic) { //I assume if ContentFormat == "MPEG" that the delivered file is an unencrypted mp3. //I also assume that if DrmType != Adrm, the file will be an mp3. //These assumptions may be wrong, and only time and bug reports will tell. - var outputFormat = - contentLic?.ContentMetadata?.ContentReference?.ContentFormat == "MPEG" || - (config.AllowLibationFixup && config.DecryptToLossy) ? + + bool encrypted = contentLic.DrmType == AudibleApi.Common.DrmType.Adrm; + + var outputFormat = !encrypted || (config.AllowLibationFixup && config.DecryptToLossy) ? OutputFormat.Mp3 : OutputFormat.M4b; - var audiobookDlLic = new DownloadLicense + var audiobookDlLic = new DownloadOptions ( contentLic?.ContentMetadata?.ContentUrl?.OfflineUrl, Resources.USER_AGENT - ) { - AudibleKey = contentLic?.Voucher?.Key, AudibleIV = contentLic?.Voucher?.Iv, OutputFormat = outputFormat, - TrimOutputToChapterLength = config.StripAudibleBrandAudio + TrimOutputToChapterLength = config.StripAudibleBrandAudio, + RetainEncryptedFile = config.RetainAaxFile && encrypted }; if (config.AllowLibationFixup || outputFormat == OutputFormat.Mp3) diff --git a/FileManager/FileNamingTemplate.cs b/FileManager/FileNamingTemplate.cs index 0b4dca26..1dba7e0f 100644 --- a/FileManager/FileNamingTemplate.cs +++ b/FileManager/FileNamingTemplate.cs @@ -29,14 +29,14 @@ namespace FileManager public string IllegalCharacterReplacements { get; set; } /// Generate a valid path for this file or directory - public string GetFilePath() + public string GetFilePath(bool returnFirstExisting = false) { var filename = Template; foreach (var r in ParameterReplacements) filename = filename.Replace($"<{formatKey(r.Key)}>", formatValue(r.Value)); - return FileUtility.GetValidFilename(filename, IllegalCharacterReplacements); + return FileUtility.GetValidFilename(filename, IllegalCharacterReplacements, returnFirstExisting); } private static string formatKey(string key) diff --git a/FileManager/FileUtility.cs b/FileManager/FileUtility.cs index 025c63a8..61d44847 100644 --- a/FileManager/FileUtility.cs +++ b/FileManager/FileUtility.cs @@ -48,7 +48,7 @@ namespace FileManager ///
- ensure uniqueness ///
- enforce max file length ///
- public static string GetValidFilename(string path, string illegalCharacterReplacements = "") + public static string GetValidFilename(string path, string illegalCharacterReplacements = "", bool returnFirstExisting = false) { ArgumentValidator.EnsureNotNull(path, nameof(path)); @@ -69,7 +69,7 @@ namespace FileManager fullfilename = removeInvalidWhitespace(fullfilename); var i = 0; - while (File.Exists(fullfilename)) + while (File.Exists(fullfilename) && !returnFirstExisting) { var increm = $" ({++i})"; fullfilename = fileStem.Truncate(MAX_FILENAME_LENGTH - increm.Length - extension.Length) + increm + extension; diff --git a/LibationFileManager/Configuration.cs b/LibationFileManager/Configuration.cs index ae872e2c..767973fc 100644 --- a/LibationFileManager/Configuration.cs +++ b/LibationFileManager/Configuration.cs @@ -116,6 +116,13 @@ namespace LibationFileManager get => persistentDictionary.GetNonString(nameof(SplitFilesByChapter)); set => persistentDictionary.SetNonString(nameof(SplitFilesByChapter), value); } + + [Description("Retain the Aax file after successfully decrypting")] + public bool RetainAaxFile + { + get => persistentDictionary.GetNonString(nameof(RetainAaxFile)); + set => persistentDictionary.SetNonString(nameof(RetainAaxFile), value); + } public enum BadBookAction { diff --git a/LibationFileManager/Templates.cs b/LibationFileManager/Templates.cs index 4c427de5..b2826c15 100644 --- a/LibationFileManager/Templates.cs +++ b/LibationFileManager/Templates.cs @@ -230,9 +230,9 @@ namespace LibationFileManager #region to file name /// USES LIVE CONFIGURATION VALUES - public string GetFilename(LibraryBookDto libraryBookDto, string dirFullPath, string extension) + public string GetFilename(LibraryBookDto libraryBookDto, string dirFullPath, string extension, bool returnFirstExisting = false) => getFileNamingTemplate(libraryBookDto, Configuration.Instance.FileTemplate, dirFullPath, extension) - .GetFilePath(); + .GetFilePath(returnFirstExisting); #endregion } From 4c66010afe7f9c09f2a36dfb0331352c966c685b Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Sun, 8 May 2022 14:25:34 -0600 Subject: [PATCH 2/9] Add user settings for mp3 encoding. --- AaxDecrypter/AaxDecrypter.csproj | 2 +- AaxDecrypter/AaxcDownloadConvertBase.cs | 30 + AaxDecrypter/AaxcDownloadMultiConverter.cs | 2 +- AaxDecrypter/AaxcDownloadSingleConverter.cs | 2 +- AaxDecrypter/DownloadOptions.cs | 4 + AppScaffolding/LibationScaffolding.cs | 23 + FileLiberator/DownloadDecryptBook.cs | 33 +- LibationFileManager/Configuration.cs | 49 ++ .../Dialogs/SettingsDialog.AudioSettings.cs | 47 ++ .../Dialogs/SettingsDialog.Designer.cs | 533 ++++++++++++++++-- LibationWinForms/Dialogs/SettingsDialog.cs | 44 +- 11 files changed, 694 insertions(+), 75 deletions(-) create mode 100644 LibationWinForms/Dialogs/SettingsDialog.AudioSettings.cs diff --git a/AaxDecrypter/AaxDecrypter.csproj b/AaxDecrypter/AaxDecrypter.csproj index 2657a607..ee73efcd 100644 --- a/AaxDecrypter/AaxDecrypter.csproj +++ b/AaxDecrypter/AaxDecrypter.csproj @@ -6,7 +6,7 @@ - + diff --git a/AaxDecrypter/AaxcDownloadConvertBase.cs b/AaxDecrypter/AaxcDownloadConvertBase.cs index 1567d8b3..72c9722e 100644 --- a/AaxDecrypter/AaxcDownloadConvertBase.cs +++ b/AaxDecrypter/AaxcDownloadConvertBase.cs @@ -25,6 +25,36 @@ namespace AaxDecrypter { AaxFile = new AaxFile(InputFileStream); + if (DownloadOptions.StripUnabridged) + { + AaxFile.AppleTags.Title = AaxFile.AppleTags.TitleSansUnabridged; + AaxFile.AppleTags.Album = AaxFile.AppleTags.Album?.Replace(" (Unabridged)", ""); + } + + //Finishing configuring lame encoder. + if (DownloadOptions.OutputFormat == OutputFormat.Mp3) + { + double bitrateMultiple = 1; + + if (AaxFile.AudioChannels == 2) + { + if (DownloadOptions.Downsample) + bitrateMultiple = 0.5; + else + DownloadOptions.LameConfig.Mode = NAudio.Lame.MPEGMode.Stereo; + } + + if (DownloadOptions.MatchSourceBitrate) + { + int kbps = (int)(AaxFile.AverageBitrate * bitrateMultiple / 1024); + + if (DownloadOptions.LameConfig.VBR is null) + DownloadOptions.LameConfig.BitRate = kbps; + else if (DownloadOptions.LameConfig.VBR == NAudio.Lame.VBRMode.ABR) + DownloadOptions.LameConfig.ABRRateKbps = kbps; + } + } + OnRetrievedTitle(AaxFile.AppleTags.TitleSansUnabridged); OnRetrievedAuthors(AaxFile.AppleTags.FirstAuthor ?? "[unknown]"); OnRetrievedNarrators(AaxFile.AppleTags.Narrator ?? "[unknown]"); diff --git a/AaxDecrypter/AaxcDownloadMultiConverter.cs b/AaxDecrypter/AaxcDownloadMultiConverter.cs index 82e8d047..18b6851a 100644 --- a/AaxDecrypter/AaxcDownloadMultiConverter.cs +++ b/AaxDecrypter/AaxcDownloadMultiConverter.cs @@ -115,7 +115,7 @@ That naming may not be desirable for everyone, but it's an easy change to instea { createOutputFileStream(++chapterCount, splitChapters, newSplitCallback); ((NAudio.Lame.LameConfig)newSplitCallback.UserState).ID3.Track = chapterCount.ToString(); - }, null, DownloadOptions.TrimOutputToChapterLength); + }, DownloadOptions.LameConfig, DownloadOptions.TrimOutputToChapterLength); } private void createOutputFileStream(int currentChapter, ChapterInfo splitChapters, NewSplitCallback newSplitCallback) diff --git a/AaxDecrypter/AaxcDownloadSingleConverter.cs b/AaxDecrypter/AaxcDownloadSingleConverter.cs index e9492d20..243cc7c4 100644 --- a/AaxDecrypter/AaxcDownloadSingleConverter.cs +++ b/AaxDecrypter/AaxcDownloadSingleConverter.cs @@ -38,7 +38,7 @@ namespace AaxDecrypter var decryptionResult = DownloadOptions.OutputFormat == OutputFormat.M4b ? AaxFile.ConvertToMp4a(outputFile, DownloadOptions.ChapterInfo, DownloadOptions.TrimOutputToChapterLength) - : AaxFile.ConvertToMp3(outputFile, null, DownloadOptions.ChapterInfo, DownloadOptions.TrimOutputToChapterLength); + : AaxFile.ConvertToMp3(outputFile, DownloadOptions.LameConfig, DownloadOptions.ChapterInfo, DownloadOptions.TrimOutputToChapterLength); AaxFile.ConversionProgressUpdate -= AaxFile_ConversionProgressUpdate; DownloadOptions.ChapterInfo = AaxFile.Chapters; diff --git a/AaxDecrypter/DownloadOptions.cs b/AaxDecrypter/DownloadOptions.cs index 6105b1ed..b5af20f9 100644 --- a/AaxDecrypter/DownloadOptions.cs +++ b/AaxDecrypter/DownloadOptions.cs @@ -12,7 +12,11 @@ namespace AaxDecrypter public OutputFormat OutputFormat { get; init; } public bool TrimOutputToChapterLength { get; init; } public bool RetainEncryptedFile { get; init; } + public bool StripUnabridged { get; init; } public ChapterInfo ChapterInfo { get; set; } + public NAudio.Lame.LameConfig LameConfig { get; set; } + public bool Downsample { get; set; } + public bool MatchSourceBitrate { get; set; } public DownloadOptions(string downloadUrl, string userAgent) { diff --git a/AppScaffolding/LibationScaffolding.cs b/AppScaffolding/LibationScaffolding.cs index 1317a097..c6be3bc3 100644 --- a/AppScaffolding/LibationScaffolding.cs +++ b/AppScaffolding/LibationScaffolding.cs @@ -81,12 +81,35 @@ namespace AppScaffolding if (!config.Exists(nameof(config.SplitFilesByChapter))) config.SplitFilesByChapter = false; + if (!config.Exists(nameof(config.StripUnabridged))) + config.StripUnabridged = false; + if (!config.Exists(nameof(config.StripAudibleBrandAudio))) config.StripAudibleBrandAudio = false; if (!config.Exists(nameof(config.RetainAaxFile))) config.RetainAaxFile = false; + + if (!config.Exists(nameof(config.LameTargetBitrate))) + config.LameTargetBitrate = false; + + if (!config.Exists(nameof(config.LameDownsampleMono))) + config.LameDownsampleMono = true; + + if (!config.Exists(nameof(config.LameBitrate))) + config.LameBitrate = 64; + + if (!config.Exists(nameof(config.LameConstantBitrate))) + config.LameConstantBitrate = false; + + if (!config.Exists(nameof(config.LameMatchSourceBR))) + config.LameMatchSourceBR = true; + + if (!config.Exists(nameof(config.LameVBRQuality))) + config.LameVBRQuality = 2; + + if (!config.Exists(nameof(config.FolderTemplate))) config.FolderTemplate = Templates.Folder.DefaultTemplate; diff --git a/FileLiberator/DownloadDecryptBook.cs b/FileLiberator/DownloadDecryptBook.cs index 654936f8..4db73c1e 100644 --- a/FileLiberator/DownloadDecryptBook.cs +++ b/FileLiberator/DownloadDecryptBook.cs @@ -120,7 +120,6 @@ namespace FileLiberator abDownloader.DecryptProgressUpdate += OnStreamingProgressChanged; abDownloader.DecryptTimeRemaining += OnStreamingTimeRemaining; - abDownloader.RetrievedTitle += OnTitleDiscovered; abDownloader.RetrievedAuthors += OnAuthorsDiscovered; abDownloader.RetrievedNarrators += OnNarratorsDiscovered; @@ -157,8 +156,11 @@ namespace FileLiberator AudibleKey = contentLic?.Voucher?.Key, AudibleIV = contentLic?.Voucher?.Iv, OutputFormat = outputFormat, - TrimOutputToChapterLength = config.StripAudibleBrandAudio, - RetainEncryptedFile = config.RetainAaxFile && encrypted + TrimOutputToChapterLength = config.AllowLibationFixup && config.StripAudibleBrandAudio, + RetainEncryptedFile = config.RetainAaxFile && encrypted, + StripUnabridged = config.AllowLibationFixup && config.StripUnabridged, + Downsample = config.AllowLibationFixup && config.LameDownsampleMono, + MatchSourceBitrate = config.AllowLibationFixup && config.LameMatchSourceBR && config.LameTargetBitrate, }; if (config.AllowLibationFixup || outputFormat == OutputFormat.Mp3) @@ -184,6 +186,31 @@ namespace FileLiberator } } + NAudio.Lame.LameConfig lameConfig = new(); + + + lameConfig.Mode = NAudio.Lame.MPEGMode.Mono; + + if (config.LameTargetBitrate) + { + if (config.LameConstantBitrate) + lameConfig.BitRate = config.LameBitrate; + else + { + lameConfig.ABRRateKbps = config.LameBitrate; + lameConfig.VBR = NAudio.Lame.VBRMode.ABR; + lameConfig.WriteVBRTag = true; + } + } + else + { + lameConfig.VBR = NAudio.Lame.VBRMode.Default; + lameConfig.VBRQuality = config.LameVBRQuality; + lameConfig.WriteVBRTag = true; + } + + audiobookDlLic.LameConfig = lameConfig; + return audiobookDlLic; } diff --git a/LibationFileManager/Configuration.cs b/LibationFileManager/Configuration.cs index 767973fc..de24635f 100644 --- a/LibationFileManager/Configuration.cs +++ b/LibationFileManager/Configuration.cs @@ -96,6 +96,13 @@ namespace LibationFileManager set => persistentDictionary.SetNonString(nameof(AllowLibationFixup), value); } + [Description("Strip \"(Unabridged)\" from audiobook metadata tags")] + public bool StripUnabridged + { + get => persistentDictionary.GetNonString(nameof(StripUnabridged)); + set => persistentDictionary.SetNonString(nameof(StripUnabridged), value); + } + [Description("Allow Libation to remove audible branding from the start\r\nand end of audiobooks. (e.g. \"This is Audible\")")] public bool StripAudibleBrandAudio { @@ -124,6 +131,48 @@ namespace LibationFileManager set => persistentDictionary.SetNonString(nameof(RetainAaxFile), value); } + [Description("Lame encoder target. true = Bitrate, false = Quality")] + public bool LameTargetBitrate + { + get => persistentDictionary.GetNonString(nameof(LameTargetBitrate)); + set => persistentDictionary.SetNonString(nameof(LameTargetBitrate), value); + } + + [Description("Lame encoder downsamples to mono")] + public bool LameDownsampleMono + { + get => persistentDictionary.GetNonString(nameof(LameDownsampleMono)); + set => persistentDictionary.SetNonString(nameof(LameDownsampleMono), value); + } + + [Description("Lame target bitrate [16,320]")] + public int LameBitrate + { + get => persistentDictionary.GetNonString(nameof(LameBitrate)); + set => persistentDictionary.SetNonString(nameof(LameBitrate), value); + } + + [Description("Restrict encoder to constant bitrate?")] + public bool LameConstantBitrate + { + get => persistentDictionary.GetNonString(nameof(LameConstantBitrate)); + set => persistentDictionary.SetNonString(nameof(LameConstantBitrate), value); + } + + [Description("Match the source bitrate?")] + public bool LameMatchSourceBR + { + get => persistentDictionary.GetNonString(nameof(LameMatchSourceBR)); + set => persistentDictionary.SetNonString(nameof(LameMatchSourceBR), value); + } + + [Description("Lame target VBR quality [10,100]")] + public int LameVBRQuality + { + get => persistentDictionary.GetNonString(nameof(LameVBRQuality)); + set => persistentDictionary.SetNonString(nameof(LameVBRQuality), value); + } + public enum BadBookAction { [Description("Ask each time what action to take.")] diff --git a/LibationWinForms/Dialogs/SettingsDialog.AudioSettings.cs b/LibationWinForms/Dialogs/SettingsDialog.AudioSettings.cs new file mode 100644 index 00000000..712ed7a3 --- /dev/null +++ b/LibationWinForms/Dialogs/SettingsDialog.AudioSettings.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LibationWinForms.Dialogs +{ + partial class SettingsDialog + { + private void lameTargetRb_CheckedChanged(object sender, EventArgs e) + { + lameBitrateGb.Enabled = lameTargetBitrateRb.Checked; + lameQualityGb.Enabled = !lameTargetBitrateRb.Checked; + } + + private void LameMatchSourceBRCbox_CheckedChanged(object sender, EventArgs e) + { + lameBitrateTb.Enabled = !LameMatchSourceBRCbox.Checked; + lameConstantBitrateCbox.Enabled = !LameMatchSourceBRCbox.Checked; + } + + private void convertFormatRb_CheckedChanged(object sender, EventArgs e) + { + lameOptionsGb.Enabled = convertLossyRb.Checked; + lameTargetRb_CheckedChanged(sender, e); + LameMatchSourceBRCbox_CheckedChanged(sender, e); + } + private void allowLibationFixupCbox_CheckedChanged(object sender, EventArgs e) + { + convertLosslessRb.Enabled = allowLibationFixupCbox.Checked; + convertLossyRb.Enabled = allowLibationFixupCbox.Checked; + splitFilesByChapterCbox.Enabled = allowLibationFixupCbox.Checked; + stripUnabridgedCbox.Enabled = allowLibationFixupCbox.Enabled; + stripAudibleBrandingCbox.Enabled = allowLibationFixupCbox.Checked; + + if (!allowLibationFixupCbox.Checked) + { + convertLosslessRb.Checked = true; + splitFilesByChapterCbox.Checked = false; + stripUnabridgedCbox.Checked = false; + stripAudibleBrandingCbox.Checked = false; + } + } + + } +} diff --git a/LibationWinForms/Dialogs/SettingsDialog.Designer.cs b/LibationWinForms/Dialogs/SettingsDialog.Designer.cs index 8119def8..42ec8bd7 100644 --- a/LibationWinForms/Dialogs/SettingsDialog.Designer.cs +++ b/LibationWinForms/Dialogs/SettingsDialog.Designer.cs @@ -39,7 +39,6 @@ this.badBookRetryRb = new System.Windows.Forms.RadioButton(); this.badBookAbortRb = new System.Windows.Forms.RadioButton(); this.badBookAskRb = new System.Windows.Forms.RadioButton(); - this.decryptAndConvertGb = new System.Windows.Forms.GroupBox(); this.stripAudibleBrandingCbox = new System.Windows.Forms.CheckBox(); this.splitFilesByChapterCbox = new System.Windows.Forms.CheckBox(); this.allowLibationFixupCbox = new System.Windows.Forms.CheckBox(); @@ -67,8 +66,40 @@ this.folderTemplateBtn = new System.Windows.Forms.Button(); this.folderTemplateTb = new System.Windows.Forms.TextBox(); this.folderTemplateLbl = new System.Windows.Forms.Label(); + this.tab4AudioFileOptions = new System.Windows.Forms.TabPage(); + this.lameOptionsGb = new System.Windows.Forms.GroupBox(); + this.lameDownsampleMonoCbox = new System.Windows.Forms.CheckBox(); + this.lameBitrateGb = new System.Windows.Forms.GroupBox(); + this.LameMatchSourceBRCbox = new System.Windows.Forms.CheckBox(); + this.lameConstantBitrateCbox = new System.Windows.Forms.CheckBox(); + this.label7 = new System.Windows.Forms.Label(); + this.label6 = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.label11 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.lameBitrateTb = new System.Windows.Forms.TrackBar(); + this.label1 = new System.Windows.Forms.Label(); + this.lameQualityGb = new System.Windows.Forms.GroupBox(); + this.label19 = new System.Windows.Forms.Label(); + this.label18 = new System.Windows.Forms.Label(); + this.label17 = new System.Windows.Forms.Label(); + this.label16 = new System.Windows.Forms.Label(); + this.label12 = new System.Windows.Forms.Label(); + this.label15 = new System.Windows.Forms.Label(); + this.label9 = new System.Windows.Forms.Label(); + this.label8 = new System.Windows.Forms.Label(); + this.label13 = new System.Windows.Forms.Label(); + this.label10 = new System.Windows.Forms.Label(); + this.label14 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.lameVBRQualityTb = new System.Windows.Forms.TrackBar(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.lameTargetQualityRb = new System.Windows.Forms.RadioButton(); + this.lameTargetBitrateRb = new System.Windows.Forms.RadioButton(); + this.stripUnabridgedCbox = new System.Windows.Forms.CheckBox(); + this.retainAaxFileCbox = new System.Windows.Forms.CheckBox(); this.badBookGb.SuspendLayout(); - this.decryptAndConvertGb.SuspendLayout(); this.tabControl.SuspendLayout(); this.tab1ImportantSettings.SuspendLayout(); this.booksGb.SuspendLayout(); @@ -76,6 +107,13 @@ this.tab3DownloadDecrypt.SuspendLayout(); this.inProgressFilesGb.SuspendLayout(); this.customFileNamingGb.SuspendLayout(); + this.tab4AudioFileOptions.SuspendLayout(); + this.lameOptionsGb.SuspendLayout(); + this.lameBitrateGb.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.lameBitrateTb)).BeginInit(); + this.lameQualityGb.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.lameVBRQualityTb)).BeginInit(); + this.groupBox2.SuspendLayout(); this.SuspendLayout(); // // booksLocationDescLbl @@ -101,7 +139,7 @@ // saveBtn // this.saveBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.saveBtn.Location = new System.Drawing.Point(714, 523); + this.saveBtn.Location = new System.Drawing.Point(667, 441); this.saveBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.saveBtn.Name = "saveBtn"; this.saveBtn.Size = new System.Drawing.Size(88, 27); @@ -114,7 +152,7 @@ // this.cancelBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.cancelBtn.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelBtn.Location = new System.Drawing.Point(832, 523); + this.cancelBtn.Location = new System.Drawing.Point(785, 441); this.cancelBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.cancelBtn.Name = "cancelBtn"; this.cancelBtn.Size = new System.Drawing.Size(88, 27); @@ -149,9 +187,9 @@ this.badBookGb.Controls.Add(this.badBookRetryRb); this.badBookGb.Controls.Add(this.badBookAbortRb); this.badBookGb.Controls.Add(this.badBookAskRb); - this.badBookGb.Location = new System.Drawing.Point(371, 6); + this.badBookGb.Location = new System.Drawing.Point(7, 6); this.badBookGb.Name = "badBookGb"; - this.badBookGb.Size = new System.Drawing.Size(524, 168); + this.badBookGb.Size = new System.Drawing.Size(888, 76); this.badBookGb.TabIndex = 13; this.badBookGb.TabStop = false; this.badBookGb.Text = "[bad book desc]"; @@ -159,7 +197,7 @@ // badBookIgnoreRb // this.badBookIgnoreRb.AutoSize = true; - this.badBookIgnoreRb.Location = new System.Drawing.Point(6, 124); + this.badBookIgnoreRb.Location = new System.Drawing.Point(384, 47); this.badBookIgnoreRb.Name = "badBookIgnoreRb"; this.badBookIgnoreRb.Size = new System.Drawing.Size(94, 19); this.badBookIgnoreRb.TabIndex = 17; @@ -170,7 +208,7 @@ // badBookRetryRb // this.badBookRetryRb.AutoSize = true; - this.badBookRetryRb.Location = new System.Drawing.Point(6, 90); + this.badBookRetryRb.Location = new System.Drawing.Point(5, 47); this.badBookRetryRb.Name = "badBookRetryRb"; this.badBookRetryRb.Size = new System.Drawing.Size(84, 19); this.badBookRetryRb.TabIndex = 16; @@ -181,7 +219,7 @@ // badBookAbortRb // this.badBookAbortRb.AutoSize = true; - this.badBookAbortRb.Location = new System.Drawing.Point(6, 56); + this.badBookAbortRb.Location = new System.Drawing.Point(384, 22); this.badBookAbortRb.Name = "badBookAbortRb"; this.badBookAbortRb.Size = new System.Drawing.Size(88, 19); this.badBookAbortRb.TabIndex = 15; @@ -200,34 +238,20 @@ this.badBookAskRb.Text = "[ask desc]"; this.badBookAskRb.UseVisualStyleBackColor = true; // - // decryptAndConvertGb - // - this.decryptAndConvertGb.Controls.Add(this.stripAudibleBrandingCbox); - this.decryptAndConvertGb.Controls.Add(this.splitFilesByChapterCbox); - this.decryptAndConvertGb.Controls.Add(this.allowLibationFixupCbox); - this.decryptAndConvertGb.Controls.Add(this.convertLossyRb); - this.decryptAndConvertGb.Controls.Add(this.convertLosslessRb); - this.decryptAndConvertGb.Location = new System.Drawing.Point(6, 6); - this.decryptAndConvertGb.Name = "decryptAndConvertGb"; - this.decryptAndConvertGb.Size = new System.Drawing.Size(359, 168); - this.decryptAndConvertGb.TabIndex = 9; - this.decryptAndConvertGb.TabStop = false; - this.decryptAndConvertGb.Text = "Decrypt and convert"; - // // stripAudibleBrandingCbox // this.stripAudibleBrandingCbox.AutoSize = true; - this.stripAudibleBrandingCbox.Location = new System.Drawing.Point(6, 72); + this.stripAudibleBrandingCbox.Location = new System.Drawing.Point(19, 118); this.stripAudibleBrandingCbox.Name = "stripAudibleBrandingCbox"; - this.stripAudibleBrandingCbox.Size = new System.Drawing.Size(174, 19); + this.stripAudibleBrandingCbox.Size = new System.Drawing.Size(143, 34); this.stripAudibleBrandingCbox.TabIndex = 13; - this.stripAudibleBrandingCbox.Text = "[StripAudibleBranding desc]"; + this.stripAudibleBrandingCbox.Text = "[StripAudibleBranding\r\ndesc]"; this.stripAudibleBrandingCbox.UseVisualStyleBackColor = true; // // splitFilesByChapterCbox // this.splitFilesByChapterCbox.AutoSize = true; - this.splitFilesByChapterCbox.Location = new System.Drawing.Point(6, 48); + this.splitFilesByChapterCbox.Location = new System.Drawing.Point(19, 68); this.splitFilesByChapterCbox.Name = "splitFilesByChapterCbox"; this.splitFilesByChapterCbox.Size = new System.Drawing.Size(162, 19); this.splitFilesByChapterCbox.TabIndex = 13; @@ -239,7 +263,7 @@ this.allowLibationFixupCbox.AutoSize = true; this.allowLibationFixupCbox.Checked = true; this.allowLibationFixupCbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.allowLibationFixupCbox.Location = new System.Drawing.Point(6, 23); + this.allowLibationFixupCbox.Location = new System.Drawing.Point(19, 18); this.allowLibationFixupCbox.Name = "allowLibationFixupCbox"; this.allowLibationFixupCbox.Size = new System.Drawing.Size(163, 19); this.allowLibationFixupCbox.TabIndex = 10; @@ -250,24 +274,26 @@ // convertLossyRb // this.convertLossyRb.AutoSize = true; - this.convertLossyRb.Location = new System.Drawing.Point(6, 143); + this.convertLossyRb.Location = new System.Drawing.Point(19, 182); this.convertLossyRb.Name = "convertLossyRb"; this.convertLossyRb.Size = new System.Drawing.Size(329, 19); this.convertLossyRb.TabIndex = 12; this.convertLossyRb.Text = "Download my books as .MP3 files (transcode if necessary)"; this.convertLossyRb.UseVisualStyleBackColor = true; + this.convertLossyRb.CheckedChanged += new System.EventHandler(this.convertFormatRb_CheckedChanged); // // convertLosslessRb // this.convertLosslessRb.AutoSize = true; this.convertLosslessRb.Checked = true; - this.convertLosslessRb.Location = new System.Drawing.Point(6, 118); + this.convertLosslessRb.Location = new System.Drawing.Point(19, 157); this.convertLosslessRb.Name = "convertLosslessRb"; this.convertLosslessRb.Size = new System.Drawing.Size(335, 19); this.convertLosslessRb.TabIndex = 11; this.convertLosslessRb.TabStop = true; this.convertLosslessRb.Text = "Download my books in the original audio format (Lossless)"; this.convertLosslessRb.UseVisualStyleBackColor = true; + this.convertLosslessRb.CheckedChanged += new System.EventHandler(this.convertFormatRb_CheckedChanged); // // inProgressSelectControl // @@ -276,7 +302,7 @@ this.inProgressSelectControl.Location = new System.Drawing.Point(7, 68); this.inProgressSelectControl.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); this.inProgressSelectControl.Name = "inProgressSelectControl"; - this.inProgressSelectControl.Size = new System.Drawing.Size(875, 52); + this.inProgressSelectControl.Size = new System.Drawing.Size(828, 52); this.inProgressSelectControl.TabIndex = 19; // // logsBtn @@ -296,7 +322,7 @@ this.booksSelectControl.Location = new System.Drawing.Point(7, 37); this.booksSelectControl.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); this.booksSelectControl.Name = "booksSelectControl"; - this.booksSelectControl.Size = new System.Drawing.Size(876, 87); + this.booksSelectControl.Size = new System.Drawing.Size(829, 87); this.booksSelectControl.TabIndex = 2; // // loggingLevelLbl @@ -325,10 +351,11 @@ this.tabControl.Controls.Add(this.tab1ImportantSettings); this.tabControl.Controls.Add(this.tab2ImportLibrary); this.tabControl.Controls.Add(this.tab3DownloadDecrypt); + this.tabControl.Controls.Add(this.tab4AudioFileOptions); this.tabControl.Location = new System.Drawing.Point(12, 12); this.tabControl.Name = "tabControl"; this.tabControl.SelectedIndex = 0; - this.tabControl.Size = new System.Drawing.Size(909, 505); + this.tabControl.Size = new System.Drawing.Size(862, 423); this.tabControl.TabIndex = 100; // // tab1ImportantSettings @@ -340,7 +367,7 @@ this.tab1ImportantSettings.Location = new System.Drawing.Point(4, 24); this.tab1ImportantSettings.Name = "tab1ImportantSettings"; this.tab1ImportantSettings.Padding = new System.Windows.Forms.Padding(3); - this.tab1ImportantSettings.Size = new System.Drawing.Size(901, 459); + this.tab1ImportantSettings.Size = new System.Drawing.Size(854, 395); this.tab1ImportantSettings.TabIndex = 0; this.tab1ImportantSettings.Text = "Important settings"; this.tab1ImportantSettings.UseVisualStyleBackColor = true; @@ -353,7 +380,7 @@ this.booksGb.Controls.Add(this.booksLocationDescLbl); this.booksGb.Location = new System.Drawing.Point(6, 6); this.booksGb.Name = "booksGb"; - this.booksGb.Size = new System.Drawing.Size(889, 129); + this.booksGb.Size = new System.Drawing.Size(842, 129); this.booksGb.TabIndex = 0; this.booksGb.TabStop = false; this.booksGb.Text = "Books location"; @@ -366,7 +393,7 @@ this.tab2ImportLibrary.Location = new System.Drawing.Point(4, 24); this.tab2ImportLibrary.Name = "tab2ImportLibrary"; this.tab2ImportLibrary.Padding = new System.Windows.Forms.Padding(3); - this.tab2ImportLibrary.Size = new System.Drawing.Size(901, 459); + this.tab2ImportLibrary.Size = new System.Drawing.Size(854, 395); this.tab2ImportLibrary.TabIndex = 1; this.tab2ImportLibrary.Text = "Import library"; this.tab2ImportLibrary.UseVisualStyleBackColor = true; @@ -385,12 +412,11 @@ // this.tab3DownloadDecrypt.Controls.Add(this.inProgressFilesGb); this.tab3DownloadDecrypt.Controls.Add(this.customFileNamingGb); - this.tab3DownloadDecrypt.Controls.Add(this.decryptAndConvertGb); this.tab3DownloadDecrypt.Controls.Add(this.badBookGb); this.tab3DownloadDecrypt.Location = new System.Drawing.Point(4, 24); this.tab3DownloadDecrypt.Name = "tab3DownloadDecrypt"; this.tab3DownloadDecrypt.Padding = new System.Windows.Forms.Padding(3); - this.tab3DownloadDecrypt.Size = new System.Drawing.Size(901, 477); + this.tab3DownloadDecrypt.Size = new System.Drawing.Size(854, 395); this.tab3DownloadDecrypt.TabIndex = 2; this.tab3DownloadDecrypt.Text = "Download/Decrypt"; this.tab3DownloadDecrypt.UseVisualStyleBackColor = true; @@ -401,9 +427,9 @@ | System.Windows.Forms.AnchorStyles.Right))); this.inProgressFilesGb.Controls.Add(this.inProgressDescLbl); this.inProgressFilesGb.Controls.Add(this.inProgressSelectControl); - this.inProgressFilesGb.Location = new System.Drawing.Point(7, 343); + this.inProgressFilesGb.Location = new System.Drawing.Point(7, 251); this.inProgressFilesGb.Name = "inProgressFilesGb"; - this.inProgressFilesGb.Size = new System.Drawing.Size(888, 128); + this.inProgressFilesGb.Size = new System.Drawing.Size(841, 128); this.inProgressFilesGb.TabIndex = 21; this.inProgressFilesGb.TabStop = false; this.inProgressFilesGb.Text = "In progress files"; @@ -421,9 +447,9 @@ this.customFileNamingGb.Controls.Add(this.folderTemplateBtn); this.customFileNamingGb.Controls.Add(this.folderTemplateTb); this.customFileNamingGb.Controls.Add(this.folderTemplateLbl); - this.customFileNamingGb.Location = new System.Drawing.Point(7, 180); + this.customFileNamingGb.Location = new System.Drawing.Point(7, 88); this.customFileNamingGb.Name = "customFileNamingGb"; - this.customFileNamingGb.Size = new System.Drawing.Size(888, 157); + this.customFileNamingGb.Size = new System.Drawing.Size(841, 157); this.customFileNamingGb.TabIndex = 20; this.customFileNamingGb.TabStop = false; this.customFileNamingGb.Text = "Custom file naming"; @@ -431,7 +457,7 @@ // chapterFileTemplateBtn // this.chapterFileTemplateBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.chapterFileTemplateBtn.Location = new System.Drawing.Point(808, 124); + this.chapterFileTemplateBtn.Location = new System.Drawing.Point(761, 124); this.chapterFileTemplateBtn.Name = "chapterFileTemplateBtn"; this.chapterFileTemplateBtn.Size = new System.Drawing.Size(75, 23); this.chapterFileTemplateBtn.TabIndex = 8; @@ -446,7 +472,7 @@ this.chapterFileTemplateTb.Location = new System.Drawing.Point(6, 125); this.chapterFileTemplateTb.Name = "chapterFileTemplateTb"; this.chapterFileTemplateTb.ReadOnly = true; - this.chapterFileTemplateTb.Size = new System.Drawing.Size(796, 23); + this.chapterFileTemplateTb.Size = new System.Drawing.Size(749, 23); this.chapterFileTemplateTb.TabIndex = 7; // // chapterFileTemplateLbl @@ -461,7 +487,7 @@ // fileTemplateBtn // this.fileTemplateBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.fileTemplateBtn.Location = new System.Drawing.Point(808, 80); + this.fileTemplateBtn.Location = new System.Drawing.Point(761, 80); this.fileTemplateBtn.Name = "fileTemplateBtn"; this.fileTemplateBtn.Size = new System.Drawing.Size(75, 23); this.fileTemplateBtn.TabIndex = 5; @@ -476,7 +502,7 @@ this.fileTemplateTb.Location = new System.Drawing.Point(6, 81); this.fileTemplateTb.Name = "fileTemplateTb"; this.fileTemplateTb.ReadOnly = true; - this.fileTemplateTb.Size = new System.Drawing.Size(796, 23); + this.fileTemplateTb.Size = new System.Drawing.Size(749, 23); this.fileTemplateTb.TabIndex = 4; // // fileTemplateLbl @@ -491,7 +517,7 @@ // folderTemplateBtn // this.folderTemplateBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.folderTemplateBtn.Location = new System.Drawing.Point(807, 36); + this.folderTemplateBtn.Location = new System.Drawing.Point(760, 36); this.folderTemplateBtn.Name = "folderTemplateBtn"; this.folderTemplateBtn.Size = new System.Drawing.Size(75, 23); this.folderTemplateBtn.TabIndex = 2; @@ -506,7 +532,7 @@ this.folderTemplateTb.Location = new System.Drawing.Point(5, 37); this.folderTemplateTb.Name = "folderTemplateTb"; this.folderTemplateTb.ReadOnly = true; - this.folderTemplateTb.Size = new System.Drawing.Size(796, 23); + this.folderTemplateTb.Size = new System.Drawing.Size(749, 23); this.folderTemplateTb.TabIndex = 1; // // folderTemplateLbl @@ -518,13 +544,374 @@ this.folderTemplateLbl.TabIndex = 0; this.folderTemplateLbl.Text = "[folder template desc]"; // + // tab4AudioFileOptions + // + this.tab4AudioFileOptions.Controls.Add(this.lameOptionsGb); + this.tab4AudioFileOptions.Controls.Add(this.convertLossyRb); + this.tab4AudioFileOptions.Controls.Add(this.stripAudibleBrandingCbox); + this.tab4AudioFileOptions.Controls.Add(this.convertLosslessRb); + this.tab4AudioFileOptions.Controls.Add(this.stripUnabridgedCbox); + this.tab4AudioFileOptions.Controls.Add(this.splitFilesByChapterCbox); + this.tab4AudioFileOptions.Controls.Add(this.retainAaxFileCbox); + this.tab4AudioFileOptions.Controls.Add(this.allowLibationFixupCbox); + this.tab4AudioFileOptions.Location = new System.Drawing.Point(4, 24); + this.tab4AudioFileOptions.Name = "tab4AudioFileOptions"; + this.tab4AudioFileOptions.Padding = new System.Windows.Forms.Padding(3); + this.tab4AudioFileOptions.Size = new System.Drawing.Size(854, 395); + this.tab4AudioFileOptions.TabIndex = 3; + this.tab4AudioFileOptions.Text = "Audio File Options"; + this.tab4AudioFileOptions.UseVisualStyleBackColor = true; + // + // lameOptionsGb + // + this.lameOptionsGb.Controls.Add(this.lameDownsampleMonoCbox); + this.lameOptionsGb.Controls.Add(this.lameBitrateGb); + this.lameOptionsGb.Controls.Add(this.label1); + this.lameOptionsGb.Controls.Add(this.lameQualityGb); + this.lameOptionsGb.Controls.Add(this.groupBox2); + this.lameOptionsGb.Location = new System.Drawing.Point(415, 18); + this.lameOptionsGb.Name = "lameOptionsGb"; + this.lameOptionsGb.Size = new System.Drawing.Size(433, 371); + this.lameOptionsGb.TabIndex = 14; + this.lameOptionsGb.TabStop = false; + this.lameOptionsGb.Text = "Mp3 Encoding Options"; + // + // lameDownsampleMonoCbox + // + this.lameDownsampleMonoCbox.AutoSize = true; + this.lameDownsampleMonoCbox.Location = new System.Drawing.Point(234, 35); + this.lameDownsampleMonoCbox.Name = "lameDownsampleMonoCbox"; + this.lameDownsampleMonoCbox.Size = new System.Drawing.Size(184, 34); + this.lameDownsampleMonoCbox.TabIndex = 1; + this.lameDownsampleMonoCbox.Text = "Downsample stereo to mono?\r\n(Recommended)\r\n"; + this.lameDownsampleMonoCbox.UseVisualStyleBackColor = true; + // + // lameBitrateGb + // + this.lameBitrateGb.Controls.Add(this.LameMatchSourceBRCbox); + this.lameBitrateGb.Controls.Add(this.lameConstantBitrateCbox); + this.lameBitrateGb.Controls.Add(this.label7); + this.lameBitrateGb.Controls.Add(this.label6); + this.lameBitrateGb.Controls.Add(this.label5); + this.lameBitrateGb.Controls.Add(this.label4); + this.lameBitrateGb.Controls.Add(this.label11); + this.lameBitrateGb.Controls.Add(this.label3); + this.lameBitrateGb.Controls.Add(this.lameBitrateTb); + this.lameBitrateGb.Location = new System.Drawing.Point(6, 84); + this.lameBitrateGb.Name = "lameBitrateGb"; + this.lameBitrateGb.Size = new System.Drawing.Size(421, 112); + this.lameBitrateGb.TabIndex = 0; + this.lameBitrateGb.TabStop = false; + this.lameBitrateGb.Text = "Bitrate"; + // + // LameMatchSourceBRCbox + // + this.LameMatchSourceBRCbox.AutoSize = true; + this.LameMatchSourceBRCbox.Location = new System.Drawing.Point(260, 87); + this.LameMatchSourceBRCbox.Name = "LameMatchSourceBRCbox"; + this.LameMatchSourceBRCbox.Size = new System.Drawing.Size(140, 19); + this.LameMatchSourceBRCbox.TabIndex = 3; + this.LameMatchSourceBRCbox.Text = "Match source bitrate?"; + this.LameMatchSourceBRCbox.UseVisualStyleBackColor = true; + this.LameMatchSourceBRCbox.CheckedChanged += new System.EventHandler(this.LameMatchSourceBRCbox_CheckedChanged); + // + // lameConstantBitrateCbox + // + this.lameConstantBitrateCbox.AutoSize = true; + this.lameConstantBitrateCbox.Location = new System.Drawing.Point(6, 87); + this.lameConstantBitrateCbox.Name = "lameConstantBitrateCbox"; + this.lameConstantBitrateCbox.Size = new System.Drawing.Size(216, 19); + this.lameConstantBitrateCbox.TabIndex = 2; + this.lameConstantBitrateCbox.Text = "Restrict encoder to constant bitrate?"; + this.lameConstantBitrateCbox.UseVisualStyleBackColor = true; + // + // label7 + // + this.label7.AutoSize = true; + this.label7.BackColor = System.Drawing.SystemColors.ControlLightLight; + this.label7.Location = new System.Drawing.Point(390, 52); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(25, 15); + this.label7.TabIndex = 1; + this.label7.Text = "320"; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.BackColor = System.Drawing.SystemColors.ControlLightLight; + this.label6.Location = new System.Drawing.Point(309, 52); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(25, 15); + this.label6.TabIndex = 1; + this.label6.Text = "256"; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.BackColor = System.Drawing.SystemColors.ControlLightLight; + this.label5.Location = new System.Drawing.Point(228, 52); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(25, 15); + this.label5.TabIndex = 1; + this.label5.Text = "192"; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.BackColor = System.Drawing.SystemColors.ControlLightLight; + this.label4.Location = new System.Drawing.Point(147, 52); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(25, 15); + this.label4.TabIndex = 1; + this.label4.Text = "128"; + // + // label11 + // + this.label11.AutoSize = true; + this.label11.BackColor = System.Drawing.SystemColors.ControlLightLight; + this.label11.Location = new System.Drawing.Point(10, 52); + this.label11.Name = "label11"; + this.label11.Size = new System.Drawing.Size(19, 15); + this.label11.TabIndex = 1; + this.label11.Text = "16"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.BackColor = System.Drawing.SystemColors.ControlLightLight; + this.label3.Location = new System.Drawing.Point(71, 52); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(19, 15); + this.label3.TabIndex = 1; + this.label3.Text = "64"; + // + // lameBitrateTb + // + this.lameBitrateTb.BackColor = System.Drawing.SystemColors.ControlLightLight; + this.lameBitrateTb.LargeChange = 2; + this.lameBitrateTb.Location = new System.Drawing.Point(6, 22); + this.lameBitrateTb.Maximum = 320; + this.lameBitrateTb.Minimum = 16; + this.lameBitrateTb.Name = "lameBitrateTb"; + this.lameBitrateTb.Size = new System.Drawing.Size(409, 45); + this.lameBitrateTb.TabIndex = 0; + this.lameBitrateTb.TickFrequency = 16; + this.lameBitrateTb.Value = 64; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Enabled = false; + this.label1.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point); + this.label1.Location = new System.Drawing.Point(6, 353); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(172, 15); + this.label1.TabIndex = 1; + this.label1.Text = "Using L.A.M.E. encoding engine"; + // + // lameQualityGb + // + this.lameQualityGb.Controls.Add(this.label19); + this.lameQualityGb.Controls.Add(this.label18); + this.lameQualityGb.Controls.Add(this.label17); + this.lameQualityGb.Controls.Add(this.label16); + this.lameQualityGb.Controls.Add(this.label12); + this.lameQualityGb.Controls.Add(this.label15); + this.lameQualityGb.Controls.Add(this.label9); + this.lameQualityGb.Controls.Add(this.label8); + this.lameQualityGb.Controls.Add(this.label13); + this.lameQualityGb.Controls.Add(this.label10); + this.lameQualityGb.Controls.Add(this.label14); + this.lameQualityGb.Controls.Add(this.label2); + this.lameQualityGb.Controls.Add(this.lameVBRQualityTb); + this.lameQualityGb.Location = new System.Drawing.Point(6, 202); + this.lameQualityGb.Name = "lameQualityGb"; + this.lameQualityGb.Size = new System.Drawing.Size(421, 109); + this.lameQualityGb.TabIndex = 0; + this.lameQualityGb.TabStop = false; + this.lameQualityGb.Text = "Quality"; + // + // label19 + // + this.label19.AutoSize = true; + this.label19.Location = new System.Drawing.Point(349, 52); + this.label19.Name = "label19"; + this.label19.Size = new System.Drawing.Size(20, 15); + this.label19.TabIndex = 1; + this.label19.Text = "V8"; + // + // label18 + // + this.label18.AutoSize = true; + this.label18.Location = new System.Drawing.Point(307, 52); + this.label18.Name = "label18"; + this.label18.Size = new System.Drawing.Size(20, 15); + this.label18.TabIndex = 1; + this.label18.Text = "V7"; + // + // label17 + // + this.label17.AutoSize = true; + this.label17.Location = new System.Drawing.Point(265, 52); + this.label17.Name = "label17"; + this.label17.Size = new System.Drawing.Size(20, 15); + this.label17.TabIndex = 1; + this.label17.Text = "V6"; + // + // label16 + // + this.label16.AutoSize = true; + this.label16.Location = new System.Drawing.Point(223, 52); + this.label16.Name = "label16"; + this.label16.Size = new System.Drawing.Size(20, 15); + this.label16.TabIndex = 1; + this.label16.Text = "V5"; + // + // label12 + // + this.label12.AutoSize = true; + this.label12.Location = new System.Drawing.Point(182, 52); + this.label12.Name = "label12"; + this.label12.Size = new System.Drawing.Size(20, 15); + this.label12.TabIndex = 1; + this.label12.Text = "V4"; + // + // label15 + // + this.label15.AutoSize = true; + this.label15.Location = new System.Drawing.Point(140, 52); + this.label15.Name = "label15"; + this.label15.Size = new System.Drawing.Size(20, 15); + this.label15.TabIndex = 1; + this.label15.Text = "V3"; + // + // label9 + // + this.label9.AutoSize = true; + this.label9.Location = new System.Drawing.Point(97, 52); + this.label9.Name = "label9"; + this.label9.Size = new System.Drawing.Size(20, 15); + this.label9.TabIndex = 1; + this.label9.Text = "V2"; + // + // label8 + // + this.label8.AutoSize = true; + this.label8.Location = new System.Drawing.Point(391, 52); + this.label8.Name = "label8"; + this.label8.Size = new System.Drawing.Size(20, 15); + this.label8.TabIndex = 1; + this.label8.Text = "V9"; + // + // label13 + // + this.label13.AutoSize = true; + this.label13.Location = new System.Drawing.Point(376, 81); + this.label13.Name = "label13"; + this.label13.Size = new System.Drawing.Size(39, 15); + this.label13.TabIndex = 1; + this.label13.Text = "Lower"; + // + // label10 + // + this.label10.AutoSize = true; + this.label10.Location = new System.Drawing.Point(6, 81); + this.label10.Name = "label10"; + this.label10.Size = new System.Drawing.Size(43, 15); + this.label10.TabIndex = 1; + this.label10.Text = "Higher"; + // + // label14 + // + this.label14.AutoSize = true; + this.label14.Location = new System.Drawing.Point(56, 52); + this.label14.Name = "label14"; + this.label14.Size = new System.Drawing.Size(20, 15); + this.label14.TabIndex = 1; + this.label14.Text = "V1"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(14, 52); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(20, 15); + this.label2.TabIndex = 1; + this.label2.Text = "V0"; + // + // lameVBRQualityTb + // + this.lameVBRQualityTb.BackColor = System.Drawing.SystemColors.ControlLightLight; + this.lameVBRQualityTb.Location = new System.Drawing.Point(10, 22); + this.lameVBRQualityTb.Maximum = 9; + this.lameVBRQualityTb.Name = "lameVBRQualityTb"; + this.lameVBRQualityTb.Size = new System.Drawing.Size(405, 45); + this.lameVBRQualityTb.TabIndex = 0; + this.lameVBRQualityTb.Value = 9; + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.lameTargetQualityRb); + this.groupBox2.Controls.Add(this.lameTargetBitrateRb); + this.groupBox2.Location = new System.Drawing.Point(6, 22); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(222, 56); + this.groupBox2.TabIndex = 0; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "Target"; + // + // lameTargetQualityRb + // + this.lameTargetQualityRb.AutoSize = true; + this.lameTargetQualityRb.Location = new System.Drawing.Point(138, 23); + this.lameTargetQualityRb.Name = "lameTargetQualityRb"; + this.lameTargetQualityRb.Size = new System.Drawing.Size(63, 19); + this.lameTargetQualityRb.TabIndex = 0; + this.lameTargetQualityRb.TabStop = true; + this.lameTargetQualityRb.Text = "Quality"; + this.lameTargetQualityRb.UseVisualStyleBackColor = true; + this.lameTargetQualityRb.CheckedChanged += new System.EventHandler(this.lameTargetRb_CheckedChanged); + // + // lameTargetBitrateRb + // + this.lameTargetBitrateRb.AutoSize = true; + this.lameTargetBitrateRb.Location = new System.Drawing.Point(6, 23); + this.lameTargetBitrateRb.Name = "lameTargetBitrateRb"; + this.lameTargetBitrateRb.Size = new System.Drawing.Size(59, 19); + this.lameTargetBitrateRb.TabIndex = 0; + this.lameTargetBitrateRb.TabStop = true; + this.lameTargetBitrateRb.Text = "Bitrate"; + this.lameTargetBitrateRb.UseVisualStyleBackColor = true; + this.lameTargetBitrateRb.CheckedChanged += new System.EventHandler(this.lameTargetRb_CheckedChanged); + // + // stripUnabridgedCbox + // + this.stripUnabridgedCbox.AutoSize = true; + this.stripUnabridgedCbox.Location = new System.Drawing.Point(19, 93); + this.stripUnabridgedCbox.Name = "stripUnabridgedCbox"; + this.stripUnabridgedCbox.Size = new System.Drawing.Size(147, 19); + this.stripUnabridgedCbox.TabIndex = 13; + this.stripUnabridgedCbox.Text = "[StripUnabridged desc]"; + this.stripUnabridgedCbox.UseVisualStyleBackColor = true; + // + // retainAaxFileCbox + // + this.retainAaxFileCbox.AutoSize = true; + this.retainAaxFileCbox.Location = new System.Drawing.Point(19, 43); + this.retainAaxFileCbox.Name = "retainAaxFileCbox"; + this.retainAaxFileCbox.Size = new System.Drawing.Size(132, 19); + this.retainAaxFileCbox.TabIndex = 10; + this.retainAaxFileCbox.Text = "[RetainAaxFile desc]"; + this.retainAaxFileCbox.UseVisualStyleBackColor = true; + this.retainAaxFileCbox.CheckedChanged += new System.EventHandler(this.allowLibationFixupCbox_CheckedChanged); + // // SettingsDialog // this.AcceptButton = this.saveBtn; this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.cancelBtn; - this.ClientSize = new System.Drawing.Size(933, 566); + this.ClientSize = new System.Drawing.Size(886, 484); this.Controls.Add(this.tabControl); this.Controls.Add(this.cancelBtn); this.Controls.Add(this.saveBtn); @@ -536,8 +923,6 @@ this.Load += new System.EventHandler(this.SettingsDialog_Load); this.badBookGb.ResumeLayout(false); this.badBookGb.PerformLayout(); - this.decryptAndConvertGb.ResumeLayout(false); - this.decryptAndConvertGb.PerformLayout(); this.tabControl.ResumeLayout(false); this.tab1ImportantSettings.ResumeLayout(false); this.tab1ImportantSettings.PerformLayout(); @@ -550,6 +935,18 @@ this.inProgressFilesGb.PerformLayout(); this.customFileNamingGb.ResumeLayout(false); this.customFileNamingGb.PerformLayout(); + this.tab4AudioFileOptions.ResumeLayout(false); + this.tab4AudioFileOptions.PerformLayout(); + this.lameOptionsGb.ResumeLayout(false); + this.lameOptionsGb.PerformLayout(); + this.lameBitrateGb.ResumeLayout(false); + this.lameBitrateGb.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.lameBitrateTb)).EndInit(); + this.lameQualityGb.ResumeLayout(false); + this.lameQualityGb.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.lameVBRQualityTb)).EndInit(); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); this.ResumeLayout(false); } @@ -567,7 +964,6 @@ private System.Windows.Forms.Button logsBtn; private System.Windows.Forms.Label loggingLevelLbl; private System.Windows.Forms.ComboBox loggingLevelCb; - private System.Windows.Forms.GroupBox decryptAndConvertGb; private System.Windows.Forms.GroupBox badBookGb; private System.Windows.Forms.RadioButton badBookRetryRb; private System.Windows.Forms.RadioButton badBookAbortRb; @@ -594,5 +990,38 @@ private System.Windows.Forms.Label folderTemplateLbl; private System.Windows.Forms.CheckBox showImportedStatsCb; private System.Windows.Forms.CheckBox stripAudibleBrandingCbox; + private System.Windows.Forms.TabPage tab4AudioFileOptions; + private System.Windows.Forms.CheckBox retainAaxFileCbox; + private System.Windows.Forms.CheckBox stripUnabridgedCbox; + private System.Windows.Forms.GroupBox lameOptionsGb; + private System.Windows.Forms.CheckBox lameDownsampleMonoCbox; + private System.Windows.Forms.GroupBox lameBitrateGb; + private System.Windows.Forms.TrackBar lameBitrateTb; + private System.Windows.Forms.GroupBox lameQualityGb; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.RadioButton lameTargetQualityRb; + private System.Windows.Forms.RadioButton lameTargetBitrateRb; + private System.Windows.Forms.CheckBox lameConstantBitrateCbox; + private System.Windows.Forms.Label label7; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label9; + private System.Windows.Forms.Label label8; + private System.Windows.Forms.TrackBar lameVBRQualityTb; + private System.Windows.Forms.Label label11; + private System.Windows.Forms.CheckBox LameMatchSourceBRCbox; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label12; + private System.Windows.Forms.Label label10; + private System.Windows.Forms.Label label15; + private System.Windows.Forms.Label label13; + private System.Windows.Forms.Label label14; + private System.Windows.Forms.Label label19; + private System.Windows.Forms.Label label18; + private System.Windows.Forms.Label label17; + private System.Windows.Forms.Label label16; } } \ No newline at end of file diff --git a/LibationWinForms/Dialogs/SettingsDialog.cs b/LibationWinForms/Dialogs/SettingsDialog.cs index 452b0bc9..6ee4ca74 100644 --- a/LibationWinForms/Dialogs/SettingsDialog.cs +++ b/LibationWinForms/Dialogs/SettingsDialog.cs @@ -35,6 +35,8 @@ namespace LibationWinForms.Dialogs this.allowLibationFixupCbox.Text = desc(nameof(config.AllowLibationFixup)); this.splitFilesByChapterCbox.Text = desc(nameof(config.SplitFilesByChapter)); this.stripAudibleBrandingCbox.Text = desc(nameof(config.StripAudibleBrandAudio)); + this.retainAaxFileCbox.Text = desc(nameof(config.RetainAaxFile)); + this.stripUnabridgedCbox.Text = desc(nameof(config.StripUnabridged)); booksSelectControl.SetSearchTitle("books location"); booksSelectControl.SetDirectoryItems( @@ -52,11 +54,24 @@ namespace LibationWinForms.Dialogs importEpisodesCb.Checked = config.ImportEpisodes; downloadEpisodesCb.Checked = config.DownloadEpisodes; allowLibationFixupCbox.Checked = config.AllowLibationFixup; + retainAaxFileCbox.Checked = config.RetainAaxFile; convertLosslessRb.Checked = !config.DecryptToLossy; convertLossyRb.Checked = config.DecryptToLossy; - splitFilesByChapterCbox.Checked = config.SplitFilesByChapter; + stripUnabridgedCbox.Checked = config.StripUnabridged; stripAudibleBrandingCbox.Checked = config.StripAudibleBrandAudio; + splitFilesByChapterCbox.Checked = config.SplitFilesByChapter; + lameTargetBitrateRb.Checked = config.LameTargetBitrate; + lameTargetQualityRb.Checked = !config.LameTargetBitrate; + lameDownsampleMonoCbox.Checked = config.LameDownsampleMono; + lameBitrateTb.Value = config.LameBitrate; + lameConstantBitrateCbox.Checked = config.LameConstantBitrate; + LameMatchSourceBRCbox.Checked = config.LameMatchSourceBR; + lameVBRQualityTb.Value = config.LameVBRQuality; + + lameTargetRb_CheckedChanged(this, e); + LameMatchSourceBRCbox_CheckedChanged(this, e); + convertFormatRb_CheckedChanged(this, e); allowLibationFixupCbox_CheckedChanged(this, e); inProgressSelectControl.SetDirectoryItems(new() @@ -92,21 +107,6 @@ namespace LibationWinForms.Dialogs chapterFileTemplateTb.Text = config.ChapterFileTemplate; } - private void allowLibationFixupCbox_CheckedChanged(object sender, EventArgs e) - { - convertLosslessRb.Enabled = allowLibationFixupCbox.Checked; - convertLossyRb.Enabled = allowLibationFixupCbox.Checked; - splitFilesByChapterCbox.Enabled = allowLibationFixupCbox.Checked; - stripAudibleBrandingCbox.Enabled =allowLibationFixupCbox.Checked; - - if (!allowLibationFixupCbox.Checked) - { - convertLosslessRb.Checked = true; - splitFilesByChapterCbox.Checked = false; - stripAudibleBrandingCbox.Checked = false; - } - } - private void logsBtn_Click(object sender, EventArgs e) => Go.To.Folder(Configuration.Instance.LibationFiles); private void folderTemplateBtn_Click(object sender, EventArgs e) => editTemplate(Templates.Folder, folderTemplateTb); @@ -176,9 +176,18 @@ namespace LibationWinForms.Dialogs config.ImportEpisodes = importEpisodesCb.Checked; config.DownloadEpisodes = downloadEpisodesCb.Checked; config.AllowLibationFixup = allowLibationFixupCbox.Checked; + config.RetainAaxFile = retainAaxFileCbox.Checked; config.DecryptToLossy = convertLossyRb.Checked; - config.SplitFilesByChapter = splitFilesByChapterCbox.Checked; + config.StripUnabridged = stripUnabridgedCbox.Checked; config.StripAudibleBrandAudio = stripAudibleBrandingCbox.Checked; + config.SplitFilesByChapter = splitFilesByChapterCbox.Checked; + + config.LameTargetBitrate = lameTargetBitrateRb.Checked; + config.LameDownsampleMono = lameDownsampleMonoCbox.Checked; + config.LameBitrate = lameBitrateTb.Value; + config.LameConstantBitrate = lameConstantBitrateCbox.Checked; + config.LameMatchSourceBR = LameMatchSourceBRCbox.Checked; + config.LameVBRQuality = lameVBRQualityTb.Value; config.InProgress = inProgressSelectControl.SelectedDirectory; @@ -202,5 +211,6 @@ namespace LibationWinForms.Dialogs this.DialogResult = DialogResult.Cancel; this.Close(); } + } } From 420f4b9d5db761bc048aaa68e6b6530092aa5e17 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Sun, 8 May 2022 15:46:33 -0600 Subject: [PATCH 3/9] Add optional cue sheet --- AaxDecrypter/AudiobookDownloadBase.cs | 2 + AaxDecrypter/DownloadOptions.cs | 3 +- AppScaffolding/LibationScaffolding.cs | 47 ++++++++++--------- FileLiberator/DownloadDecryptBook.cs | 1 + LibationFileManager/Configuration.cs | 35 ++++++++------ .../Dialogs/SettingsDialog.AudioSettings.cs | 3 +- .../Dialogs/SettingsDialog.Designer.cs | 32 ++++++++++--- LibationWinForms/Dialogs/SettingsDialog.cs | 27 ++++++----- 8 files changed, 92 insertions(+), 58 deletions(-) diff --git a/AaxDecrypter/AudiobookDownloadBase.cs b/AaxDecrypter/AudiobookDownloadBase.cs index 0de90a27..e9bb0a0e 100644 --- a/AaxDecrypter/AudiobookDownloadBase.cs +++ b/AaxDecrypter/AudiobookDownloadBase.cs @@ -98,6 +98,8 @@ namespace AaxDecrypter protected bool Step_CreateCue() { + if (!DownloadOptions.CreateCueSheet) return true; + // not a critical step. its failure should not prevent future steps from running try { diff --git a/AaxDecrypter/DownloadOptions.cs b/AaxDecrypter/DownloadOptions.cs index b5af20f9..efeb2664 100644 --- a/AaxDecrypter/DownloadOptions.cs +++ b/AaxDecrypter/DownloadOptions.cs @@ -13,10 +13,11 @@ namespace AaxDecrypter public bool TrimOutputToChapterLength { get; init; } public bool RetainEncryptedFile { get; init; } public bool StripUnabridged { get; init; } + public bool CreateCueSheet { get; init; } public ChapterInfo ChapterInfo { get; set; } public NAudio.Lame.LameConfig LameConfig { get; set; } public bool Downsample { get; set; } - public bool MatchSourceBitrate { get; set; } + public bool MatchSourceBitrate { get; set; } public DownloadOptions(string downloadUrl, string userAgent) { diff --git a/AppScaffolding/LibationScaffolding.cs b/AppScaffolding/LibationScaffolding.cs index c6be3bc3..21d3126c 100644 --- a/AppScaffolding/LibationScaffolding.cs +++ b/AppScaffolding/LibationScaffolding.cs @@ -66,30 +66,23 @@ namespace AppScaffolding if (!config.Exists(nameof(config.AllowLibationFixup))) config.AllowLibationFixup = true; - if (!config.Exists(nameof(config.DecryptToLossy))) - config.DecryptToLossy = false; + if (!config.Exists(nameof(config.CreateCueSheet))) + config.CreateCueSheet = true; - if (!config.Exists(nameof(config.BadBook))) - config.BadBook = Configuration.BadBookAction.Ask; - - if (!config.Exists(nameof(config.DownloadEpisodes))) - config.DownloadEpisodes = true; - - if (!config.Exists(nameof(config.ImportEpisodes))) - config.ImportEpisodes = true; - - if (!config.Exists(nameof(config.SplitFilesByChapter))) - config.SplitFilesByChapter = false; - - if (!config.Exists(nameof(config.StripUnabridged))) - config.StripUnabridged = false; - - if (!config.Exists(nameof(config.StripAudibleBrandAudio))) - config.StripAudibleBrandAudio = false; - if (!config.Exists(nameof(config.RetainAaxFile))) config.RetainAaxFile = false; + if (!config.Exists(nameof(config.SplitFilesByChapter))) + config.SplitFilesByChapter = false; + + if (!config.Exists(nameof(config.StripUnabridged))) + config.StripUnabridged = false; + + if (!config.Exists(nameof(config.StripAudibleBrandAudio))) + config.StripAudibleBrandAudio = false; + + if (!config.Exists(nameof(config.DecryptToLossy))) + config.DecryptToLossy = false; if (!config.Exists(nameof(config.LameTargetBitrate))) config.LameTargetBitrate = false; @@ -109,6 +102,17 @@ namespace AppScaffolding if (!config.Exists(nameof(config.LameVBRQuality))) config.LameVBRQuality = 2; + if (!config.Exists(nameof(config.BadBook))) + config.BadBook = Configuration.BadBookAction.Ask; + + if (!config.Exists(nameof(config.ShowImportedStats))) + config.ShowImportedStats = true; + + if (!config.Exists(nameof(config.ImportEpisodes))) + config.ImportEpisodes = true; + + if (!config.Exists(nameof(config.DownloadEpisodes))) + config.DownloadEpisodes = true; if (!config.Exists(nameof(config.FolderTemplate))) config.FolderTemplate = Templates.Folder.DefaultTemplate; @@ -118,9 +122,6 @@ namespace AppScaffolding if (!config.Exists(nameof(config.ChapterFileTemplate))) config.ChapterFileTemplate = Templates.ChapterFile.DefaultTemplate; - - if (!config.Exists(nameof(config.ShowImportedStats))) - config.ShowImportedStats = true; } /// Initialize logging. Run after migration diff --git a/FileLiberator/DownloadDecryptBook.cs b/FileLiberator/DownloadDecryptBook.cs index 4db73c1e..7bca70e2 100644 --- a/FileLiberator/DownloadDecryptBook.cs +++ b/FileLiberator/DownloadDecryptBook.cs @@ -161,6 +161,7 @@ namespace FileLiberator StripUnabridged = config.AllowLibationFixup && config.StripUnabridged, Downsample = config.AllowLibationFixup && config.LameDownsampleMono, MatchSourceBitrate = config.AllowLibationFixup && config.LameMatchSourceBR && config.LameTargetBitrate, + CreateCueSheet = config.CreateCueSheet }; if (config.AllowLibationFixup || outputFormat == OutputFormat.Mp3) diff --git a/LibationFileManager/Configuration.cs b/LibationFileManager/Configuration.cs index de24635f..ff508e95 100644 --- a/LibationFileManager/Configuration.cs +++ b/LibationFileManager/Configuration.cs @@ -96,6 +96,27 @@ namespace LibationFileManager set => persistentDictionary.SetNonString(nameof(AllowLibationFixup), value); } + [Description("Create a cue sheet (.cue)")] + public bool CreateCueSheet + { + get => persistentDictionary.GetNonString(nameof(CreateCueSheet)); + set => persistentDictionary.SetNonString(nameof(CreateCueSheet), value); + } + + [Description("Retain the Aax file after successfully decrypting")] + public bool RetainAaxFile + { + get => persistentDictionary.GetNonString(nameof(RetainAaxFile)); + set => persistentDictionary.SetNonString(nameof(RetainAaxFile), value); + } + + [Description("Split my books into multiple files by chapter")] + public bool SplitFilesByChapter + { + get => persistentDictionary.GetNonString(nameof(SplitFilesByChapter)); + set => persistentDictionary.SetNonString(nameof(SplitFilesByChapter), value); + } + [Description("Strip \"(Unabridged)\" from audiobook metadata tags")] public bool StripUnabridged { @@ -116,20 +137,6 @@ namespace LibationFileManager get => persistentDictionary.GetNonString(nameof(DecryptToLossy)); set => persistentDictionary.SetNonString(nameof(DecryptToLossy), value); } - - [Description("Split my books into multiple files by chapter")] - public bool SplitFilesByChapter - { - get => persistentDictionary.GetNonString(nameof(SplitFilesByChapter)); - set => persistentDictionary.SetNonString(nameof(SplitFilesByChapter), value); - } - - [Description("Retain the Aax file after successfully decrypting")] - public bool RetainAaxFile - { - get => persistentDictionary.GetNonString(nameof(RetainAaxFile)); - set => persistentDictionary.SetNonString(nameof(RetainAaxFile), value); - } [Description("Lame encoder target. true = Bitrate, false = Quality")] public bool LameTargetBitrate diff --git a/LibationWinForms/Dialogs/SettingsDialog.AudioSettings.cs b/LibationWinForms/Dialogs/SettingsDialog.AudioSettings.cs index 712ed7a3..6b45db4e 100644 --- a/LibationWinForms/Dialogs/SettingsDialog.AudioSettings.cs +++ b/LibationWinForms/Dialogs/SettingsDialog.AudioSettings.cs @@ -31,7 +31,7 @@ namespace LibationWinForms.Dialogs convertLosslessRb.Enabled = allowLibationFixupCbox.Checked; convertLossyRb.Enabled = allowLibationFixupCbox.Checked; splitFilesByChapterCbox.Enabled = allowLibationFixupCbox.Checked; - stripUnabridgedCbox.Enabled = allowLibationFixupCbox.Enabled; + stripUnabridgedCbox.Enabled = allowLibationFixupCbox.Checked; stripAudibleBrandingCbox.Enabled = allowLibationFixupCbox.Checked; if (!allowLibationFixupCbox.Checked) @@ -42,6 +42,5 @@ namespace LibationWinForms.Dialogs stripAudibleBrandingCbox.Checked = false; } } - } } diff --git a/LibationWinForms/Dialogs/SettingsDialog.Designer.cs b/LibationWinForms/Dialogs/SettingsDialog.Designer.cs index 42ec8bd7..94aa5cdc 100644 --- a/LibationWinForms/Dialogs/SettingsDialog.Designer.cs +++ b/LibationWinForms/Dialogs/SettingsDialog.Designer.cs @@ -99,6 +99,7 @@ this.lameTargetBitrateRb = new System.Windows.Forms.RadioButton(); this.stripUnabridgedCbox = new System.Windows.Forms.CheckBox(); this.retainAaxFileCbox = new System.Windows.Forms.CheckBox(); + this.createCueSheetCbox = new System.Windows.Forms.CheckBox(); this.badBookGb.SuspendLayout(); this.tabControl.SuspendLayout(); this.tab1ImportantSettings.SuspendLayout(); @@ -241,7 +242,7 @@ // stripAudibleBrandingCbox // this.stripAudibleBrandingCbox.AutoSize = true; - this.stripAudibleBrandingCbox.Location = new System.Drawing.Point(19, 118); + this.stripAudibleBrandingCbox.Location = new System.Drawing.Point(19, 143); this.stripAudibleBrandingCbox.Name = "stripAudibleBrandingCbox"; this.stripAudibleBrandingCbox.Size = new System.Drawing.Size(143, 34); this.stripAudibleBrandingCbox.TabIndex = 13; @@ -251,7 +252,7 @@ // splitFilesByChapterCbox // this.splitFilesByChapterCbox.AutoSize = true; - this.splitFilesByChapterCbox.Location = new System.Drawing.Point(19, 68); + this.splitFilesByChapterCbox.Location = new System.Drawing.Point(19, 93); this.splitFilesByChapterCbox.Name = "splitFilesByChapterCbox"; this.splitFilesByChapterCbox.Size = new System.Drawing.Size(162, 19); this.splitFilesByChapterCbox.TabIndex = 13; @@ -274,7 +275,7 @@ // convertLossyRb // this.convertLossyRb.AutoSize = true; - this.convertLossyRb.Location = new System.Drawing.Point(19, 182); + this.convertLossyRb.Location = new System.Drawing.Point(19, 207); this.convertLossyRb.Name = "convertLossyRb"; this.convertLossyRb.Size = new System.Drawing.Size(329, 19); this.convertLossyRb.TabIndex = 12; @@ -286,7 +287,7 @@ // this.convertLosslessRb.AutoSize = true; this.convertLosslessRb.Checked = true; - this.convertLosslessRb.Location = new System.Drawing.Point(19, 157); + this.convertLosslessRb.Location = new System.Drawing.Point(19, 182); this.convertLosslessRb.Name = "convertLosslessRb"; this.convertLosslessRb.Size = new System.Drawing.Size(335, 19); this.convertLosslessRb.TabIndex = 11; @@ -553,6 +554,7 @@ this.tab4AudioFileOptions.Controls.Add(this.stripUnabridgedCbox); this.tab4AudioFileOptions.Controls.Add(this.splitFilesByChapterCbox); this.tab4AudioFileOptions.Controls.Add(this.retainAaxFileCbox); + this.tab4AudioFileOptions.Controls.Add(this.createCueSheetCbox); this.tab4AudioFileOptions.Controls.Add(this.allowLibationFixupCbox); this.tab4AudioFileOptions.Location = new System.Drawing.Point(4, 24); this.tab4AudioFileOptions.Name = "tab4AudioFileOptions"; @@ -688,12 +690,13 @@ // lameBitrateTb // this.lameBitrateTb.BackColor = System.Drawing.SystemColors.ControlLightLight; - this.lameBitrateTb.LargeChange = 2; + this.lameBitrateTb.LargeChange = 32; this.lameBitrateTb.Location = new System.Drawing.Point(6, 22); this.lameBitrateTb.Maximum = 320; this.lameBitrateTb.Minimum = 16; this.lameBitrateTb.Name = "lameBitrateTb"; this.lameBitrateTb.Size = new System.Drawing.Size(409, 45); + this.lameBitrateTb.SmallChange = 8; this.lameBitrateTb.TabIndex = 0; this.lameBitrateTb.TickFrequency = 16; this.lameBitrateTb.Value = 64; @@ -842,6 +845,7 @@ // lameVBRQualityTb // this.lameVBRQualityTb.BackColor = System.Drawing.SystemColors.ControlLightLight; + this.lameVBRQualityTb.LargeChange = 1; this.lameVBRQualityTb.Location = new System.Drawing.Point(10, 22); this.lameVBRQualityTb.Maximum = 9; this.lameVBRQualityTb.Name = "lameVBRQualityTb"; @@ -887,7 +891,7 @@ // stripUnabridgedCbox // this.stripUnabridgedCbox.AutoSize = true; - this.stripUnabridgedCbox.Location = new System.Drawing.Point(19, 93); + this.stripUnabridgedCbox.Location = new System.Drawing.Point(19, 118); this.stripUnabridgedCbox.Name = "stripUnabridgedCbox"; this.stripUnabridgedCbox.Size = new System.Drawing.Size(147, 19); this.stripUnabridgedCbox.TabIndex = 13; @@ -897,7 +901,7 @@ // retainAaxFileCbox // this.retainAaxFileCbox.AutoSize = true; - this.retainAaxFileCbox.Location = new System.Drawing.Point(19, 43); + this.retainAaxFileCbox.Location = new System.Drawing.Point(19, 68); this.retainAaxFileCbox.Name = "retainAaxFileCbox"; this.retainAaxFileCbox.Size = new System.Drawing.Size(132, 19); this.retainAaxFileCbox.TabIndex = 10; @@ -905,6 +909,19 @@ this.retainAaxFileCbox.UseVisualStyleBackColor = true; this.retainAaxFileCbox.CheckedChanged += new System.EventHandler(this.allowLibationFixupCbox_CheckedChanged); // + // createCueSheetCbox + // + this.createCueSheetCbox.AutoSize = true; + this.createCueSheetCbox.Checked = true; + this.createCueSheetCbox.CheckState = System.Windows.Forms.CheckState.Checked; + this.createCueSheetCbox.Location = new System.Drawing.Point(19, 43); + this.createCueSheetCbox.Name = "createCueSheetCbox"; + this.createCueSheetCbox.Size = new System.Drawing.Size(145, 19); + this.createCueSheetCbox.TabIndex = 10; + this.createCueSheetCbox.Text = "[CreateCueSheet desc]"; + this.createCueSheetCbox.UseVisualStyleBackColor = true; + this.createCueSheetCbox.CheckedChanged += new System.EventHandler(this.allowLibationFixupCbox_CheckedChanged); + // // SettingsDialog // this.AcceptButton = this.saveBtn; @@ -1023,5 +1040,6 @@ private System.Windows.Forms.Label label18; private System.Windows.Forms.Label label17; private System.Windows.Forms.Label label16; + private System.Windows.Forms.CheckBox createCueSheetCbox; } } \ No newline at end of file diff --git a/LibationWinForms/Dialogs/SettingsDialog.cs b/LibationWinForms/Dialogs/SettingsDialog.cs index 6ee4ca74..0bc85858 100644 --- a/LibationWinForms/Dialogs/SettingsDialog.cs +++ b/LibationWinForms/Dialogs/SettingsDialog.cs @@ -37,6 +37,7 @@ namespace LibationWinForms.Dialogs this.stripAudibleBrandingCbox.Text = desc(nameof(config.StripAudibleBrandAudio)); this.retainAaxFileCbox.Text = desc(nameof(config.RetainAaxFile)); this.stripUnabridgedCbox.Text = desc(nameof(config.StripUnabridged)); + this.createCueSheetCbox.Text = desc(nameof(config.CreateCueSheet)); booksSelectControl.SetSearchTitle("books location"); booksSelectControl.SetDirectoryItems( @@ -50,16 +51,14 @@ namespace LibationWinForms.Dialogs "Books"); booksSelectControl.SelectDirectory(config.Books); - showImportedStatsCb.Checked = config.ShowImportedStats; - importEpisodesCb.Checked = config.ImportEpisodes; - downloadEpisodesCb.Checked = config.DownloadEpisodes; allowLibationFixupCbox.Checked = config.AllowLibationFixup; + createCueSheetCbox.Checked = config.CreateCueSheet; retainAaxFileCbox.Checked = config.RetainAaxFile; - convertLosslessRb.Checked = !config.DecryptToLossy; - convertLossyRb.Checked = config.DecryptToLossy; + splitFilesByChapterCbox.Checked = config.SplitFilesByChapter; stripUnabridgedCbox.Checked = config.StripUnabridged; stripAudibleBrandingCbox.Checked = config.StripAudibleBrandAudio; - splitFilesByChapterCbox.Checked = config.SplitFilesByChapter; + convertLosslessRb.Checked = !config.DecryptToLossy; + convertLossyRb.Checked = config.DecryptToLossy; lameTargetBitrateRb.Checked = config.LameTargetBitrate; lameTargetQualityRb.Checked = !config.LameTargetBitrate; @@ -69,6 +68,10 @@ namespace LibationWinForms.Dialogs LameMatchSourceBRCbox.Checked = config.LameMatchSourceBR; lameVBRQualityTb.Value = config.LameVBRQuality; + showImportedStatsCb.Checked = config.ShowImportedStats; + importEpisodesCb.Checked = config.ImportEpisodes; + downloadEpisodesCb.Checked = config.DownloadEpisodes; + lameTargetRb_CheckedChanged(this, e); LameMatchSourceBRCbox_CheckedChanged(this, e); convertFormatRb_CheckedChanged(this, e); @@ -172,15 +175,13 @@ namespace LibationWinForms.Dialogs MessageBoxVerboseLoggingWarning.ShowIfTrue(); } - config.ShowImportedStats = showImportedStatsCb.Checked; - config.ImportEpisodes = importEpisodesCb.Checked; - config.DownloadEpisodes = downloadEpisodesCb.Checked; config.AllowLibationFixup = allowLibationFixupCbox.Checked; + config.CreateCueSheet = createCueSheetCbox.Checked; config.RetainAaxFile = retainAaxFileCbox.Checked; - config.DecryptToLossy = convertLossyRb.Checked; + config.SplitFilesByChapter = splitFilesByChapterCbox.Checked; config.StripUnabridged = stripUnabridgedCbox.Checked; config.StripAudibleBrandAudio = stripAudibleBrandingCbox.Checked; - config.SplitFilesByChapter = splitFilesByChapterCbox.Checked; + config.DecryptToLossy = convertLossyRb.Checked; config.LameTargetBitrate = lameTargetBitrateRb.Checked; config.LameDownsampleMono = lameDownsampleMonoCbox.Checked; @@ -189,6 +190,10 @@ namespace LibationWinForms.Dialogs config.LameMatchSourceBR = LameMatchSourceBRCbox.Checked; config.LameVBRQuality = lameVBRQualityTb.Value; + config.ShowImportedStats = showImportedStatsCb.Checked; + config.ImportEpisodes = importEpisodesCb.Checked; + config.DownloadEpisodes = downloadEpisodesCb.Checked; + config.InProgress = inProgressSelectControl.SelectedDirectory; config.BadBook From 458ea6a37709d88fe75957b1e46095f3b358443f Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Sun, 8 May 2022 16:13:35 -0600 Subject: [PATCH 4/9] Fix tmp file extension to aaxc --- AaxDecrypter/AudiobookDownloadBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AaxDecrypter/AudiobookDownloadBase.cs b/AaxDecrypter/AudiobookDownloadBase.cs index e9bb0a0e..c825bf4e 100644 --- a/AaxDecrypter/AudiobookDownloadBase.cs +++ b/AaxDecrypter/AudiobookDownloadBase.cs @@ -47,7 +47,7 @@ namespace AaxDecrypter throw new DirectoryNotFoundException($"Directory does not exist: {nameof(cacheDirectory)}"); jsonDownloadState = Path.Combine(cacheDirectory, Path.GetFileName(Path.ChangeExtension(OutputFileName, ".json"))); - TempFilePath = Path.ChangeExtension(jsonDownloadState, ".tmp"); + TempFilePath = Path.ChangeExtension(jsonDownloadState, ".aaxc"); DownloadOptions = ArgumentValidator.EnsureNotNull(dlLic, nameof(dlLic)); From 2afcaebb78673f186109bb4d0414b824ff64d476 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Sun, 8 May 2022 16:31:24 -0600 Subject: [PATCH 5/9] Prevent same bok being decrypted more than once at a time --- .../BookLiberation/ProcessorAutomationController.cs | 7 ++++--- LibationWinForms/grid/ProductsGrid.cs | 9 ++++++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/LibationWinForms/BookLiberation/ProcessorAutomationController.cs b/LibationWinForms/BookLiberation/ProcessorAutomationController.cs index 064b012e..adb40eff 100644 --- a/LibationWinForms/BookLiberation/ProcessorAutomationController.cs +++ b/LibationWinForms/BookLiberation/ProcessorAutomationController.cs @@ -50,12 +50,12 @@ namespace LibationWinForms.BookLiberation public static class ProcessorAutomationController { - public static async Task BackupSingleBookAsync(LibraryBook libraryBook) + public static async Task BackupSingleBookAsync(LibraryBook libraryBook, Action onCompleteAction = null) { Serilog.Log.Logger.Information($"Begin {nameof(BackupSingleBookAsync)} {{@DebugInfo}}", new { libraryBook?.Book?.AudibleProductId }); var logMe = LogMe.RegisterForm(); - var backupBook = CreateBackupBook(logMe); + var backupBook = CreateBackupBook(logMe, onCompleteAction); // continue even if libraryBook is null. we'll display even that in the processing box await new BackupSingle(logMe, backupBook, libraryBook).RunBackupAsync(); @@ -96,13 +96,14 @@ namespace LibationWinForms.BookLiberation await new BackupLoop(logMe, downloadPdf, automatedBackupsForm).RunBackupAsync(); } - private static Processable CreateBackupBook(LogMe logMe) + private static Processable CreateBackupBook(LogMe logMe, Action onCompleteAction = null) { var downloadPdf = CreateProcessable(logMe); //Chain pdf download on DownloadDecryptBook.Completed async void onDownloadDecryptBookCompleted(object sender, LibraryBook e) { + onCompleteAction?.Invoke(e); await downloadPdf.TryProcessAsync(e); } diff --git a/LibationWinForms/grid/ProductsGrid.cs b/LibationWinForms/grid/ProductsGrid.cs index 7f933bad..821220b3 100644 --- a/LibationWinForms/grid/ProductsGrid.cs +++ b/LibationWinForms/grid/ProductsGrid.cs @@ -29,6 +29,7 @@ namespace LibationWinForms public partial class ProductsGrid : UserControl { + private static List bookConversionInProgress = new(); public event EventHandler VisibleCountChanged; // alias @@ -88,8 +89,14 @@ namespace LibationWinForms return; } + //don't try to decrypt the same book at the same time. + if (bookConversionInProgress.Contains(libraryBook.Book.AudibleProductId)) + return; + + bookConversionInProgress.Add(libraryBook.Book.AudibleProductId); + // else: liberate - await BookLiberation.ProcessorAutomationController.BackupSingleBookAsync(libraryBook); + await BookLiberation.ProcessorAutomationController.BackupSingleBookAsync(libraryBook, b => bookConversionInProgress.Remove(b.Book.AudibleProductId)); } private static void Details_Click(GridEntry liveGridEntry) From f68bf2d6b3427c0d054752b8ccaa0fa5c8264a79 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Sun, 8 May 2022 16:48:58 -0600 Subject: [PATCH 6/9] Better method for downloading only 1 book at a time. --- .../BookLiberation/ProcessorAutomationController.cs | 7 +++---- LibationWinForms/grid/GridEntry.cs | 12 ++++++++++++ LibationWinForms/grid/ProductsGrid.cs | 9 +-------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/LibationWinForms/BookLiberation/ProcessorAutomationController.cs b/LibationWinForms/BookLiberation/ProcessorAutomationController.cs index adb40eff..064b012e 100644 --- a/LibationWinForms/BookLiberation/ProcessorAutomationController.cs +++ b/LibationWinForms/BookLiberation/ProcessorAutomationController.cs @@ -50,12 +50,12 @@ namespace LibationWinForms.BookLiberation public static class ProcessorAutomationController { - public static async Task BackupSingleBookAsync(LibraryBook libraryBook, Action onCompleteAction = null) + public static async Task BackupSingleBookAsync(LibraryBook libraryBook) { Serilog.Log.Logger.Information($"Begin {nameof(BackupSingleBookAsync)} {{@DebugInfo}}", new { libraryBook?.Book?.AudibleProductId }); var logMe = LogMe.RegisterForm(); - var backupBook = CreateBackupBook(logMe, onCompleteAction); + var backupBook = CreateBackupBook(logMe); // continue even if libraryBook is null. we'll display even that in the processing box await new BackupSingle(logMe, backupBook, libraryBook).RunBackupAsync(); @@ -96,14 +96,13 @@ namespace LibationWinForms.BookLiberation await new BackupLoop(logMe, downloadPdf, automatedBackupsForm).RunBackupAsync(); } - private static Processable CreateBackupBook(LogMe logMe, Action onCompleteAction = null) + private static Processable CreateBackupBook(LogMe logMe) { var downloadPdf = CreateProcessable(logMe); //Chain pdf download on DownloadDecryptBook.Completed async void onDownloadDecryptBookCompleted(object sender, LibraryBook e) { - onCompleteAction?.Invoke(e); await downloadPdf.TryProcessAsync(e); } diff --git a/LibationWinForms/grid/GridEntry.cs b/LibationWinForms/grid/GridEntry.cs index 45afd23d..7a3ba2fc 100644 --- a/LibationWinForms/grid/GridEntry.cs +++ b/LibationWinForms/grid/GridEntry.cs @@ -10,6 +10,7 @@ using Dinah.Core.DataBinding; using Dinah.Core; using Dinah.Core.Drawing; using LibationFileManager; +using System.Threading.Tasks; namespace LibationWinForms { @@ -39,6 +40,7 @@ namespace LibationWinForms } } + public bool DownloadInProgress { get; private set; } public string ProductRating { get; private set; } public string PurchaseDate { get; private set; } public string MyRating { get; private set; } @@ -77,6 +79,16 @@ namespace LibationWinForms public GridEntry(LibraryBook libraryBook) => setLibraryBook(libraryBook); + public async Task DownloadBook() + { + if (!DownloadInProgress) + { + DownloadInProgress = true; + await BookLiberation.ProcessorAutomationController.BackupSingleBookAsync(LibraryBook); + DownloadInProgress = false; + } + } + public void UpdateLibraryBook(LibraryBook libraryBook) { if (AudibleProductId != libraryBook.Book.AudibleProductId) diff --git a/LibationWinForms/grid/ProductsGrid.cs b/LibationWinForms/grid/ProductsGrid.cs index 821220b3..d5c0dc52 100644 --- a/LibationWinForms/grid/ProductsGrid.cs +++ b/LibationWinForms/grid/ProductsGrid.cs @@ -29,7 +29,6 @@ namespace LibationWinForms public partial class ProductsGrid : UserControl { - private static List bookConversionInProgress = new(); public event EventHandler VisibleCountChanged; // alias @@ -89,14 +88,8 @@ namespace LibationWinForms return; } - //don't try to decrypt the same book at the same time. - if (bookConversionInProgress.Contains(libraryBook.Book.AudibleProductId)) - return; - - bookConversionInProgress.Add(libraryBook.Book.AudibleProductId); - // else: liberate - await BookLiberation.ProcessorAutomationController.BackupSingleBookAsync(libraryBook, b => bookConversionInProgress.Remove(b.Book.AudibleProductId)); + await liveGridEntry.DownloadBook(); } private static void Details_Click(GridEntry liveGridEntry) From eab6f71a4cf52875fd03be8cdd1614c2d1e245e5 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Sun, 8 May 2022 17:07:10 -0600 Subject: [PATCH 7/9] Don't delete temp aaxc file if download failed. --- FileLiberator/DownloadDecryptBook.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FileLiberator/DownloadDecryptBook.cs b/FileLiberator/DownloadDecryptBook.cs index 7bca70e2..b03334a0 100644 --- a/FileLiberator/DownloadDecryptBook.cs +++ b/FileLiberator/DownloadDecryptBook.cs @@ -62,7 +62,7 @@ namespace FileLiberator // decrypt failed if (!success) { - foreach (var tmpFile in entries) + foreach (var tmpFile in entries.Where(f => f.FileType != FileType.AAXC)) FileUtility.SaferDelete(tmpFile.Path); return new StatusHandler { "Decrypt failed" }; From 9a619186fd996c3339d907a0fd1d08a82483a980 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Sun, 8 May 2022 19:56:59 -0600 Subject: [PATCH 8/9] If keeping aaxc, write aaxc key to file --- AaxDecrypter/AudiobookDownloadBase.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/AaxDecrypter/AudiobookDownloadBase.cs b/AaxDecrypter/AudiobookDownloadBase.cs index c825bf4e..ef16f7d5 100644 --- a/AaxDecrypter/AudiobookDownloadBase.cs +++ b/AaxDecrypter/AudiobookDownloadBase.cs @@ -122,11 +122,20 @@ namespace AaxDecrypter { FileUtility.SaferDelete(jsonDownloadState); - if (DownloadOptions.RetainEncryptedFile) + if (DownloadOptions.AudibleKey is not null && + DownloadOptions.AudibleIV is not null && + DownloadOptions.RetainEncryptedFile) { string aaxPath = Path.ChangeExtension(TempFilePath, ".aax"); FileUtility.SaferMove(TempFilePath, aaxPath); + + //Write aax decryption key + string keyPath = Path.ChangeExtension(aaxPath, ".key"); + FileUtility.SaferDelete(keyPath); + File.WriteAllText(keyPath, $"Key={DownloadOptions.AudibleKey}\r\nIV={DownloadOptions.AudibleIV}"); + OnFileCreated(aaxPath); + OnFileCreated(keyPath); } else FileUtility.SaferDelete(TempFilePath); From 4e587e04294ed3e343d1b9928a54f25f254cfe57 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Sun, 8 May 2022 19:58:48 -0600 Subject: [PATCH 9/9] Add try block --- LibationWinForms/grid/GridEntry.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/LibationWinForms/grid/GridEntry.cs b/LibationWinForms/grid/GridEntry.cs index 7a3ba2fc..04283952 100644 --- a/LibationWinForms/grid/GridEntry.cs +++ b/LibationWinForms/grid/GridEntry.cs @@ -83,9 +83,15 @@ namespace LibationWinForms { if (!DownloadInProgress) { - DownloadInProgress = true; - await BookLiberation.ProcessorAutomationController.BackupSingleBookAsync(LibraryBook); - DownloadInProgress = false; + try + { + DownloadInProgress = true; + await BookLiberation.ProcessorAutomationController.BackupSingleBookAsync(LibraryBook); + } + finally + { + DownloadInProgress = false; + } } }