diff --git a/Source/AaxDecrypter/AaxDecrypter.csproj b/Source/AaxDecrypter/AaxDecrypter.csproj
index aea11238..3e8af26e 100644
--- a/Source/AaxDecrypter/AaxDecrypter.csproj
+++ b/Source/AaxDecrypter/AaxDecrypter.csproj
@@ -13,7 +13,7 @@
-
+
diff --git a/Source/AaxDecrypter/AaxcDownloadConvertBase.cs b/Source/AaxDecrypter/AaxcDownloadConvertBase.cs
index c42fc4d4..994c07ae 100644
--- a/Source/AaxDecrypter/AaxcDownloadConvertBase.cs
+++ b/Source/AaxDecrypter/AaxcDownloadConvertBase.cs
@@ -10,6 +10,7 @@ namespace AaxDecrypter
public event EventHandler RetrievedMetadata;
protected AaxFile AaxFile;
+ protected Mp4Operation aaxConversion;
protected AaxcDownloadConvertBase(string outFileName, string cacheDirectory, IDownloadOptions dlOptions)
: base(outFileName, cacheDirectory, dlOptions) { }
@@ -101,9 +102,9 @@ namespace AaxDecrypter
public override async Task CancelAsync()
{
IsCanceled = true;
- if (AaxFile != null)
- await AaxFile.CancelAsync();
- AaxFile?.Dispose();
+ if (aaxConversion != null)
+ await aaxConversion.CancelAsync();
+ AaxFile?.Close();
CloseInputFileStream();
}
}
diff --git a/Source/AaxDecrypter/AaxcDownloadMultiConverter.cs b/Source/AaxDecrypter/AaxcDownloadMultiConverter.cs
index a1fdb7bd..8b198665 100644
--- a/Source/AaxDecrypter/AaxcDownloadMultiConverter.cs
+++ b/Source/AaxDecrypter/AaxcDownloadMultiConverter.cs
@@ -133,32 +133,37 @@ That naming may not be desirable for everyone, but it's an easy change to instea
try
{
- ConversionResult result;
-
- AaxFile.ConversionProgressUpdate += AaxFile_ConversionProgressUpdate;
if (DownloadOptions.OutputFormat == OutputFormat.M4b)
- result = await ConvertToMultiMp4a(splitChapters);
+ aaxConversion = ConvertToMultiMp4a(splitChapters);
else
- result = await ConvertToMultiMp3(splitChapters);
+ aaxConversion = ConvertToMultiMp3(splitChapters);
- return result == ConversionResult.NoErrorsDetected;
+ aaxConversion.ConversionProgressUpdate += AaxFile_ConversionProgressUpdate;
+ await aaxConversion;
+
+ if (aaxConversion.IsCompletedSuccessfully)
+ moveMoovToBeginning(workingFileStream?.Name);
+
+ return aaxConversion.IsCompletedSuccessfully;
}
catch(Exception ex)
{
Serilog.Log.Error(ex, "AAXClean Error");
workingFileStream?.Close();
- FileUtility.SaferDelete(workingFileStream.Name);
+ if (workingFileStream?.Name is not null)
+ FileUtility.SaferDelete(workingFileStream.Name);
return false;
}
finally
{
- AaxFile.ConversionProgressUpdate -= AaxFile_ConversionProgressUpdate;
+ if (aaxConversion is not null)
+ aaxConversion.ConversionProgressUpdate -= AaxFile_ConversionProgressUpdate;
Step_DownloadAudiobook_End(zeroProgress);
}
}
- private Task ConvertToMultiMp4a(ChapterInfo splitChapters)
+ private Mp4Operation ConvertToMultiMp4a(ChapterInfo splitChapters)
{
var chapterCount = 0;
return AaxFile.ConvertToMultiMp4aAsync
@@ -169,7 +174,7 @@ That naming may not be desirable for everyone, but it's an easy change to instea
);
}
- private Task ConvertToMultiMp3(ChapterInfo splitChapters)
+ private Mp4Operation ConvertToMultiMp3(ChapterInfo splitChapters)
{
var chapterCount = 0;
return AaxFile.ConvertToMultiMp3Async
@@ -194,12 +199,26 @@ That naming may not be desirable for everyone, but it's an easy change to instea
PartsTotal = splitChapters.Count,
Title = newSplitCallback?.Chapter?.Title,
};
+
+ moveMoovToBeginning(workingFileStream?.Name);
+
newSplitCallback.OutputFile = createOutputFileStream(props);
newSplitCallback.TrackTitle = DownloadOptions.GetMultipartTitleName(props);
newSplitCallback.TrackNumber = currentChapter;
newSplitCallback.TrackCount = splitChapters.Count;
}
+ private void moveMoovToBeginning(string filename)
+ {
+ if (DownloadOptions.OutputFormat is OutputFormat.M4b
+ && DownloadOptions.MoveMoovToBeginning
+ && filename is not null
+ && File.Exists(filename))
+ {
+ Mp4File.RelocateMoovAsync(filename).GetAwaiter().GetResult();
+ }
+ }
+
private FileStream createOutputFileStream(MultiConvertFileProperties multiConvertFileProperties)
{
var fileName = DownloadOptions.GetMultipartFileName(multiConvertFileProperties);
diff --git a/Source/AaxDecrypter/AaxcDownloadSingleConverter.cs b/Source/AaxDecrypter/AaxcDownloadSingleConverter.cs
index 288c06af..bc549b44 100644
--- a/Source/AaxDecrypter/AaxcDownloadSingleConverter.cs
+++ b/Source/AaxDecrypter/AaxcDownloadSingleConverter.cs
@@ -4,6 +4,7 @@ using System.Threading.Tasks;
using AAXClean;
using AAXClean.Codecs;
using FileManager;
+using Mpeg4Lib.Util;
namespace AaxDecrypter
{
@@ -90,16 +91,29 @@ namespace AaxDecrypter
var outputFile = File.Open(OutputFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
OnFileCreated(OutputFileName);
- AaxFile.ConversionProgressUpdate += AaxFile_ConversionProgressUpdate;
try
{
- ConversionResult decryptionResult = await decryptAsync(outputFile);
- var success = decryptionResult == ConversionResult.NoErrorsDetected && !IsCanceled;
- if (success)
+ aaxConversion = decryptAsync(outputFile);
+ aaxConversion.ConversionProgressUpdate += AaxFile_ConversionProgressUpdate;
+ await aaxConversion;
+
+ outputFile.Close();
+
+ if (aaxConversion.IsCompletedSuccessfully
+ && DownloadOptions.OutputFormat is OutputFormat.M4b
+ && DownloadOptions.MoveMoovToBeginning)
+ {
+ aaxConversion.ConversionProgressUpdate -= AaxFile_ConversionProgressUpdate;
+ aaxConversion = Mp4File.RelocateMoovAsync(OutputFileName);
+ aaxConversion.ConversionProgressUpdate += AaxFile_ConversionProgressUpdate;
+ await aaxConversion;
+ }
+
+ if (aaxConversion.IsCompletedSuccessfully)
base.OnFileCreated(OutputFileName);
- return success;
+ return aaxConversion.IsCompletedSuccessfully;
}
catch(Exception ex)
{
@@ -110,13 +124,15 @@ namespace AaxDecrypter
finally
{
outputFile.Close();
- AaxFile.ConversionProgressUpdate -= AaxFile_ConversionProgressUpdate;
+
+ if (aaxConversion is not null)
+ aaxConversion.ConversionProgressUpdate -= AaxFile_ConversionProgressUpdate;
Step_DownloadAudiobook_End(zeroProgress);
}
}
- private Task decryptAsync(Stream outputFile)
+ private Mp4Operation decryptAsync(Stream outputFile)
=> DownloadOptions.OutputFormat == OutputFormat.Mp3 ?
AaxFile.ConvertToMp3Async
(
diff --git a/Source/AaxDecrypter/IDownloadOptions.cs b/Source/AaxDecrypter/IDownloadOptions.cs
index 6972f067..f67e2040 100644
--- a/Source/AaxDecrypter/IDownloadOptions.cs
+++ b/Source/AaxDecrypter/IDownloadOptions.cs
@@ -24,6 +24,7 @@ namespace AaxDecrypter
NAudio.Lame.LameConfig LameConfig { get; }
bool Downsample { get; }
bool MatchSourceBitrate { get; }
+ bool MoveMoovToBeginning { get; }
string GetMultipartFileName(MultiConvertFileProperties props);
string GetMultipartTitleName(MultiConvertFileProperties props);
Task SaveClipsAndBookmarks(string fileName);
diff --git a/Source/FileLiberator/ConvertToMp3.cs b/Source/FileLiberator/ConvertToMp3.cs
index 5ec07045..1296037a 100644
--- a/Source/FileLiberator/ConvertToMp3.cs
+++ b/Source/FileLiberator/ConvertToMp3.cs
@@ -15,12 +15,12 @@ namespace FileLiberator
public class ConvertToMp3 : AudioDecodable
{
public override string Name => "Convert to Mp3";
- private Mp4File m4bBook;
-
+ private Mp4Operation Mp4Operation;
+ private TimeSpan bookDuration;
private long fileSize;
private static string Mp3FileName(string m4bPath) => Path.ChangeExtension(m4bPath ?? "", ".mp3");
- public override Task CancelAsync() => m4bBook?.CancelAsync() ?? Task.CompletedTask;
+ public override Task CancelAsync() => Mp4Operation?.CancelAsync() ?? Task.CompletedTask;
public static bool ValidateMp3(LibraryBook libraryBook)
{
@@ -43,9 +43,9 @@ namespace FileLiberator
var proposedMp3Path = Mp3FileName(m4bPath);
if (File.Exists(proposedMp3Path) || !File.Exists(m4bPath)) continue;
- m4bBook = await Task.Run(() => new Mp4File(m4bPath, FileAccess.Read));
- m4bBook.ConversionProgressUpdate += M4bBook_ConversionProgressUpdate;
+ var m4bBook = await Task.Run(() => new Mp4File(m4bPath, FileAccess.Read));
+ bookDuration = m4bBook.Duration;
fileSize = m4bBook.InputStream.Length;
OnTitleDiscovered(m4bBook.AppleTags.Title);
@@ -66,20 +66,20 @@ namespace FileLiberator
using var mp3File = File.OpenWrite(Path.GetTempFileName());
try
{
- var result = await m4bBook.ConvertToMp3Async(mp3File, lameConfig);
+ Mp4Operation = m4bBook.ConvertToMp3Async(mp3File, lameConfig);
+ Mp4Operation.ConversionProgressUpdate += M4bBook_ConversionProgressUpdate;
+ await Mp4Operation;
- var realMp3Path = FileUtility.SaferMoveToValidPath(mp3File.Name, proposedMp3Path, Configuration.Instance.ReplacementCharacters);
- OnFileCreated(libraryBook, realMp3Path);
-
- if (result == ConversionResult.Failed)
- {
- FileUtility.SaferDelete(mp3File.Name);
- }
- else if (result == ConversionResult.Cancelled)
+ if (Mp4Operation.IsCanceled)
{
FileUtility.SaferDelete(mp3File.Name);
return new StatusHandler { "Cancelled" };
}
+ else
+ {
+ var realMp3Path = FileUtility.SaferMoveToValidPath(mp3File.Name, proposedMp3Path, Configuration.Instance.ReplacementCharacters, "mp3");
+ OnFileCreated(libraryBook, realMp3Path);
+ }
}
catch (Exception ex)
{
@@ -88,6 +88,9 @@ namespace FileLiberator
}
finally
{
+ if (Mp4Operation is not null)
+ Mp4Operation.ConversionProgressUpdate -= M4bBook_ConversionProgressUpdate;
+
m4bBook.InputStream.Close();
mp3File.Close();
}
@@ -102,14 +105,13 @@ namespace FileLiberator
private void M4bBook_ConversionProgressUpdate(object sender, ConversionProgressEventArgs e)
{
- var duration = m4bBook.Duration;
- var remainingSecsToProcess = (duration - e.ProcessPosition).TotalSeconds;
+ var remainingSecsToProcess = (bookDuration - e.ProcessPosition).TotalSeconds;
var estTimeRemaining = remainingSecsToProcess / e.ProcessSpeed;
-
+
if (double.IsNormal(estTimeRemaining))
OnStreamingTimeRemaining(TimeSpan.FromSeconds(estTimeRemaining));
- double progressPercent = 100 * e.ProcessPosition.TotalSeconds / duration.TotalSeconds;
+ double progressPercent = 100 * e.ProcessPosition.TotalSeconds / bookDuration.TotalSeconds;
OnStreamingProgressChanged(
new DownloadProgress
diff --git a/Source/FileLiberator/DownloadDecryptBook.cs b/Source/FileLiberator/DownloadDecryptBook.cs
index ea430c5d..d0010170 100644
--- a/Source/FileLiberator/DownloadDecryptBook.cs
+++ b/Source/FileLiberator/DownloadDecryptBook.cs
@@ -160,6 +160,7 @@ namespace FileLiberator
AudibleKey = contentLic?.Voucher?.Key,
AudibleIV = contentLic?.Voucher?.Iv,
OutputFormat = outputFormat,
+ MoveMoovToBeginning = config.MoveMoovToBeginning,
TrimOutputToChapterLength = config.AllowLibationFixup && config.StripAudibleBrandAudio,
RetainEncryptedFile = config.RetainAaxFile && encrypted,
StripUnabridged = config.AllowLibationFixup && config.StripUnabridged,
diff --git a/Source/FileLiberator/DownloadOptions.cs b/Source/FileLiberator/DownloadOptions.cs
index 7520ed15..c43d1bcd 100644
--- a/Source/FileLiberator/DownloadOptions.cs
+++ b/Source/FileLiberator/DownloadOptions.cs
@@ -34,6 +34,8 @@ namespace FileLiberator
public bool MatchSourceBitrate { get; init; }
public ReplacementCharacters ReplacementCharacters => Configuration.Instance.ReplacementCharacters;
+ public bool MoveMoovToBeginning { get; init; }
+
public string GetMultipartFileName(MultiConvertFileProperties props)
=> Templates.ChapterFile.GetFilename(LibraryBookDto, props);
diff --git a/Source/FileManager/FileUtility.cs b/Source/FileManager/FileUtility.cs
index a3f46de3..0b83866b 100644
--- a/Source/FileManager/FileUtility.cs
+++ b/Source/FileManager/FileUtility.cs
@@ -151,9 +151,9 @@ namespace FileManager
///
- Perform
///
- Return valid path
///
- public static string SaferMoveToValidPath(LongPath source, LongPath destination, ReplacementCharacters replacements)
+ public static string SaferMoveToValidPath(LongPath source, LongPath destination, ReplacementCharacters replacements, string extension = null)
{
- var extension = Path.GetExtension(source);
+ extension = extension ?? Path.GetExtension(source);
destination = GetValidFilename(destination, replacements, extension);
SaferMove(source, destination);
return destination;
diff --git a/Source/LibationAvalonia/Dialogs/SettingsDialog.axaml b/Source/LibationAvalonia/Dialogs/SettingsDialog.axaml
index ba5d1d62..04e1b655 100644
--- a/Source/LibationAvalonia/Dialogs/SettingsDialog.axaml
+++ b/Source/LibationAvalonia/Dialogs/SettingsDialog.axaml
@@ -526,15 +526,27 @@
Margin="0,5,0,5"
IsChecked="{Binding !AudioSettings.DecryptToLossy, Mode=TwoWay}">
-
+
+
+
+
+
+
+
+
+
Configuration.IsLinux || Configuration.IsWindows;
-
public AudioSettings(Configuration config)
{
LoadSettings(config);
@@ -411,6 +410,7 @@ namespace LibationAvalonia.Dialogs
StripUnabridged = config.StripUnabridged;
ChapterTitleTemplate = config.ChapterTitleTemplate;
DecryptToLossy = config.DecryptToLossy;
+ MoveMoovToBeginning = config.MoveMoovToBeginning;
LameTargetBitrate = config.LameTargetBitrate;
LameDownsampleMono = config.LameDownsampleMono;
LameConstantBitrate = config.LameConstantBitrate;
@@ -433,6 +433,7 @@ namespace LibationAvalonia.Dialogs
config.StripUnabridged = StripUnabridged;
config.ChapterTitleTemplate = ChapterTitleTemplate;
config.DecryptToLossy = DecryptToLossy;
+ config.MoveMoovToBeginning = MoveMoovToBeginning;
config.LameTargetBitrate = LameTargetBitrate;
config.LameDownsampleMono = LameDownsampleMono;
config.LameConstantBitrate = LameConstantBitrate;
@@ -453,6 +454,7 @@ namespace LibationAvalonia.Dialogs
public string StripAudibleBrandingText { get; } = Configuration.GetDescription(nameof(Configuration.StripAudibleBrandAudio));
public string StripUnabridgedText { get; } = Configuration.GetDescription(nameof(Configuration.StripUnabridged));
public string ChapterTitleTemplateText { get; } = Configuration.GetDescription(nameof(Configuration.ChapterTitleTemplate));
+ public string MoveMoovToBeginningText { get; } = Configuration.GetDescription(nameof(Configuration.MoveMoovToBeginning));
public bool CreateCueSheet { get; set; }
public bool DownloadCoverArt { get; set; }
@@ -462,7 +464,8 @@ namespace LibationAvalonia.Dialogs
public bool MergeOpeningAndEndCredits { get; set; }
public bool StripAudibleBrandAudio { get; set; }
public bool StripUnabridged { get; set; }
- public bool DecryptToLossy { get; set; }
+ public bool DecryptToLossy { get => _decryptToLossy; set => this.RaiseAndSetIfChanged(ref _decryptToLossy, value); }
+ public bool MoveMoovToBeginning { get; set; }
public bool LameDownsampleMono { get; set; } = Design.IsDesignMode;
public bool LameConstantBitrate { get; set; } = Design.IsDesignMode;
diff --git a/Source/LibationFileManager/Configuration.PersistentSettings.cs b/Source/LibationFileManager/Configuration.PersistentSettings.cs
index 0482a96a..e5745713 100644
--- a/Source/LibationFileManager/Configuration.PersistentSettings.cs
+++ b/Source/LibationFileManager/Configuration.PersistentSettings.cs
@@ -115,6 +115,9 @@ namespace LibationFileManager
[Description("Decrypt to lossy format?")]
public bool DecryptToLossy { get => GetNonString(defaultValue: false); set => SetNonString(value); }
+ [Description("Move the mp4 moov atom to the beginning of the file?")]
+ public bool MoveMoovToBeginning { get => GetNonString(defaultValue: false); set => SetNonString(value); }
+
[Description("Lame encoder target. true = Bitrate, false = Quality")]
public bool LameTargetBitrate { get => GetNonString(defaultValue: false); set => SetNonString(value); }
diff --git a/Source/LibationFileManager/Templates.cs b/Source/LibationFileManager/Templates.cs
index 8880efd1..e1d33236 100644
--- a/Source/LibationFileManager/Templates.cs
+++ b/Source/LibationFileManager/Templates.cs
@@ -107,9 +107,9 @@ namespace LibationFileManager
.GetFilePath(fileExtension).PathWithoutPrefix;
public const string DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
- private static Regex fileDateTagRegex { get; } = new Regex(@"", RegexOptions.Compiled | RegexOptions.IgnoreCase);
- private static Regex dateAddedTagRegex { get; } = new Regex(@"", RegexOptions.Compiled | RegexOptions.IgnoreCase);
- private static Regex datePublishedTagRegex { get; } = new Regex(@"", RegexOptions.Compiled | RegexOptions.IgnoreCase);
+ private static Regex fileDateTagRegex { get; } = new Regex(@"", RegexOptions.Compiled | RegexOptions.IgnoreCase);
+ private static Regex dateAddedTagRegex { get; } = new Regex(@"", RegexOptions.Compiled | RegexOptions.IgnoreCase);
+ private static Regex datePublishedTagRegex { get; } = new Regex(@"", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static Regex ifSeriesRegex { get; } = new Regex("(.*?)<-if series>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
internal static FileNamingTemplate getFileNamingTemplate(LibraryBookDto libraryBookDto, string template, string dirFullPath, string extension, ReplacementCharacters replacements)
diff --git a/Source/LibationWinForms/Dialogs/SettingsDialog.AudioSettings.cs b/Source/LibationWinForms/Dialogs/SettingsDialog.AudioSettings.cs
index f7aa4cf4..d26c7448 100644
--- a/Source/LibationWinForms/Dialogs/SettingsDialog.AudioSettings.cs
+++ b/Source/LibationWinForms/Dialogs/SettingsDialog.AudioSettings.cs
@@ -16,6 +16,7 @@ namespace LibationWinForms.Dialogs
this.mergeOpeningEndCreditsCbox.Text = desc(nameof(config.MergeOpeningAndEndCredits));
this.stripAudibleBrandingCbox.Text = desc(nameof(config.StripAudibleBrandAudio));
this.stripUnabridgedCbox.Text = desc(nameof(config.StripUnabridged));
+ this.moveMoovAtomCbox.Text = desc(nameof(config.MoveMoovToBeginning));
clipsBookmarksFormatCb.Items.AddRange(
new object[]
@@ -37,6 +38,7 @@ namespace LibationWinForms.Dialogs
stripAudibleBrandingCbox.Checked = config.StripAudibleBrandAudio;
convertLosslessRb.Checked = !config.DecryptToLossy;
convertLossyRb.Checked = config.DecryptToLossy;
+ moveMoovAtomCbox.Checked = config.MoveMoovToBeginning;
lameTargetBitrateRb.Checked = config.LameTargetBitrate;
lameTargetQualityRb.Checked = !config.LameTargetBitrate;
@@ -70,6 +72,7 @@ namespace LibationWinForms.Dialogs
config.StripUnabridged = stripUnabridgedCbox.Checked;
config.StripAudibleBrandAudio = stripAudibleBrandingCbox.Checked;
config.DecryptToLossy = convertLossyRb.Checked;
+ config.MoveMoovToBeginning = moveMoovAtomCbox.Checked;
config.LameTargetBitrate = lameTargetBitrateRb.Checked;
config.LameDownsampleMono = lameDownsampleMonoCbox.Checked;
@@ -107,6 +110,7 @@ namespace LibationWinForms.Dialogs
private void convertFormatRb_CheckedChanged(object sender, EventArgs e)
{
+ moveMoovAtomCbox.Enabled = convertLosslessRb.Checked;
lameTargetRb_CheckedChanged(sender, e);
LameMatchSourceBRCbox_CheckedChanged(sender, e);
}
diff --git a/Source/LibationWinForms/Dialogs/SettingsDialog.Designer.cs b/Source/LibationWinForms/Dialogs/SettingsDialog.Designer.cs
index 3c828c52..719a6e2c 100644
--- a/Source/LibationWinForms/Dialogs/SettingsDialog.Designer.cs
+++ b/Source/LibationWinForms/Dialogs/SettingsDialog.Designer.cs
@@ -76,6 +76,7 @@
this.clipsBookmarksFormatCb = new System.Windows.Forms.ComboBox();
this.downloadClipsBookmarksCbox = new System.Windows.Forms.CheckBox();
this.audiobookFixupsGb = new System.Windows.Forms.GroupBox();
+ this.moveMoovAtomCbox = new System.Windows.Forms.CheckBox();
this.stripUnabridgedCbox = new System.Windows.Forms.CheckBox();
this.chapterTitleTemplateGb = new System.Windows.Forms.GroupBox();
this.chapterTitleTemplateBtn = new System.Windows.Forms.Button();
@@ -294,7 +295,7 @@
// convertLossyRb
//
this.convertLossyRb.AutoSize = true;
- this.convertLossyRb.Location = new System.Drawing.Point(13, 136);
+ this.convertLossyRb.Location = new System.Drawing.Point(13, 158);
this.convertLossyRb.Name = "convertLossyRb";
this.convertLossyRb.Size = new System.Drawing.Size(329, 19);
this.convertLossyRb.TabIndex = 12;
@@ -675,6 +676,7 @@
//
// audiobookFixupsGb
//
+ this.audiobookFixupsGb.Controls.Add(this.moveMoovAtomCbox);
this.audiobookFixupsGb.Controls.Add(this.splitFilesByChapterCbox);
this.audiobookFixupsGb.Controls.Add(this.stripUnabridgedCbox);
this.audiobookFixupsGb.Controls.Add(this.convertLosslessRb);
@@ -682,11 +684,21 @@
this.audiobookFixupsGb.Controls.Add(this.stripAudibleBrandingCbox);
this.audiobookFixupsGb.Location = new System.Drawing.Point(6, 169);
this.audiobookFixupsGb.Name = "audiobookFixupsGb";
- this.audiobookFixupsGb.Size = new System.Drawing.Size(403, 160);
+ this.audiobookFixupsGb.Size = new System.Drawing.Size(403, 185);
this.audiobookFixupsGb.TabIndex = 19;
this.audiobookFixupsGb.TabStop = false;
this.audiobookFixupsGb.Text = "Audiobook Fix-ups";
//
+ // moveMoovAtomCbox
+ //
+ this.moveMoovAtomCbox.AutoSize = true;
+ this.moveMoovAtomCbox.Location = new System.Drawing.Point(23, 133);
+ this.moveMoovAtomCbox.Name = "moveMoovAtomCbox";
+ this.moveMoovAtomCbox.Size = new System.Drawing.Size(188, 19);
+ this.moveMoovAtomCbox.TabIndex = 14;
+ this.moveMoovAtomCbox.Text = "[MoveMoovToBeginning desc]";
+ this.moveMoovAtomCbox.UseVisualStyleBackColor = true;
+ //
// stripUnabridgedCbox
//
this.stripUnabridgedCbox.AutoSize = true;
@@ -701,7 +713,7 @@
//
this.chapterTitleTemplateGb.Controls.Add(this.chapterTitleTemplateBtn);
this.chapterTitleTemplateGb.Controls.Add(this.chapterTitleTemplateTb);
- this.chapterTitleTemplateGb.Location = new System.Drawing.Point(6, 335);
+ this.chapterTitleTemplateGb.Location = new System.Drawing.Point(6, 360);
this.chapterTitleTemplateGb.Name = "chapterTitleTemplateGb";
this.chapterTitleTemplateGb.Size = new System.Drawing.Size(842, 54);
this.chapterTitleTemplateGb.TabIndex = 18;
@@ -738,7 +750,7 @@
this.lameOptionsGb.Controls.Add(this.groupBox2);
this.lameOptionsGb.Location = new System.Drawing.Point(415, 6);
this.lameOptionsGb.Name = "lameOptionsGb";
- this.lameOptionsGb.Size = new System.Drawing.Size(433, 323);
+ this.lameOptionsGb.Size = new System.Drawing.Size(433, 348);
this.lameOptionsGb.TabIndex = 14;
this.lameOptionsGb.TabStop = false;
this.lameOptionsGb.Text = "Mp3 Encoding Options";
@@ -1240,5 +1252,6 @@
private System.Windows.Forms.CheckBox useCoverAsFolderIconCb;
private System.Windows.Forms.ComboBox clipsBookmarksFormatCb;
private System.Windows.Forms.CheckBox downloadClipsBookmarksCbox;
+ private System.Windows.Forms.CheckBox moveMoovAtomCbox;
}
}
\ No newline at end of file
diff --git a/Source/_Tests/LibationFileManager.Tests/TemplatesTests.cs b/Source/_Tests/LibationFileManager.Tests/TemplatesTests.cs
index 400565d3..da1760c6 100644
--- a/Source/_Tests/LibationFileManager.Tests/TemplatesTests.cs
+++ b/Source/_Tests/LibationFileManager.Tests/TemplatesTests.cs
@@ -153,6 +153,7 @@ namespace TemplatesTests
[DataRow("", @"C:\foo\bar", ".m4b", @"C:\foo\bar\<filedate[h]>.m4b")]
[DataRow("< filedate[yyyy]>", @"C:\foo\bar", ".m4b", @"C:\foo\bar\< filedate[yyyy]>.m4b")]
[DataRow("", @"C:\foo\bar", ".m4b", @"C:\foo\bar\<filedate[yyyy][]>.m4b")]
+ [DataRow("", @"C:\foo\bar", ".m4b", @"C:\foo\bar\<filedate[[yyyy]]>.m4b")]
[DataRow("", @"C:\foo\bar", ".m4b", @"C:\foo\bar\<filedate[yyyy[]]>.m4b")]
[DataRow("", @"C:\foo\bar", ".m4b", @"C:\foo\bar\<filedate yyyy]>.m4b")]
[DataRow("", @"C:\foo\bar", ".m4b", @"C:\foo\bar\<filedate ]yyyy]>.m4b")]