Pad final chapter to prevent tuncation from incorrect chapter info (#1246)

This commit is contained in:
MBucari 2025-05-07 23:17:39 -06:00
parent 28ba62aead
commit b11a4887d7
3 changed files with 40 additions and 14 deletions

View File

@ -8,7 +8,7 @@ namespace AaxDecrypter
{ {
public event EventHandler<AppleTags> RetrievedMetadata; public event EventHandler<AppleTags> RetrievedMetadata;
protected Mp4File AaxFile { get; private set; } public Mp4File AaxFile { get; private set; }
protected Mp4Operation AaxConversion { get; set; } protected Mp4Operation AaxConversion { get; set; }
protected AaxcDownloadConvertBase(string outFileName, string cacheDirectory, IDownloadOptions dlOptions) protected AaxcDownloadConvertBase(string outFileName, string cacheDirectory, IDownloadOptions dlOptions)

View File

@ -171,6 +171,32 @@ namespace FileLiberator
if (sender is not AaxcDownloadConvertBase converter || converter.DownloadOptions is not DownloadOptions options) if (sender is not AaxcDownloadConvertBase converter || converter.DownloadOptions is not DownloadOptions options)
return; return;
#region Prevent erroneous truncation due to incorrect chapter info
//Sometimes the chapter info is not accurate. Since AAXClean trims audio
//files to the chapters start and end, if the last chapter's end time is
//before the end of the audio file, the file will be truncated to match
//the chapter. This is never desirable, so pad the last chapter to match
//the original audio length.
var fileDuration = converter.AaxFile.Duration;
if (options.Config.StripAudibleBrandAudio)
fileDuration -= TimeSpan.FromMilliseconds(options.ContentMetadata.ChapterInfo.BrandOutroDurationMs);
var durationDelta = fileDuration - options.ChapterInfo.EndOffset;
if (durationDelta.TotalMilliseconds > 0)
{
//only fix chapters which are shorter than the file. Chapters which are longer
//than the file will be truncated to match the file length, which is correct.
var chapters = options.ChapterInfo.Chapters as List<AAXClean.Chapter>;
var lastChapter = chapters[^1];
chapters.Remove(lastChapter);
options.ChapterInfo.Add(lastChapter.Title, lastChapter.Duration + durationDelta);
}
#endregion
tags.Title ??= options.LibraryBookDto.TitleWithSubtitle; tags.Title ??= options.LibraryBookDto.TitleWithSubtitle;
tags.Album ??= tags.Title; tags.Album ??= tags.Title;
tags.Artist ??= string.Join("; ", options.LibraryBook.Book.Authors.Select(a => a.Name)); tags.Artist ??= string.Join("; ", options.LibraryBook.Book.Authors.Select(a => a.Name));

View File

@ -31,16 +31,16 @@ namespace FileLiberator
public float? SeriesNumber => LibraryBookDto.FirstSeries?.Number; public float? SeriesNumber => LibraryBookDto.FirstSeries?.Number;
public NAudio.Lame.LameConfig LameConfig { get; init; } public NAudio.Lame.LameConfig LameConfig { get; init; }
public string UserAgent => AudibleApi.Resources.Download_User_Agent; public string UserAgent => AudibleApi.Resources.Download_User_Agent;
public bool TrimOutputToChapterLength => config.AllowLibationFixup && config.StripAudibleBrandAudio; public bool TrimOutputToChapterLength => Config.AllowLibationFixup && Config.StripAudibleBrandAudio;
public bool StripUnabridged => config.AllowLibationFixup && config.StripUnabridged; public bool StripUnabridged => Config.AllowLibationFixup && Config.StripUnabridged;
public bool CreateCueSheet => config.CreateCueSheet; public bool CreateCueSheet => Config.CreateCueSheet;
public bool DownloadClipsBookmarks => config.DownloadClipsBookmarks; public bool DownloadClipsBookmarks => Config.DownloadClipsBookmarks;
public long DownloadSpeedBps => config.DownloadSpeedLimit; public long DownloadSpeedBps => Config.DownloadSpeedLimit;
public bool RetainEncryptedFile => config.RetainAaxFile; public bool RetainEncryptedFile => Config.RetainAaxFile;
public bool FixupFile => config.AllowLibationFixup; public bool FixupFile => Config.AllowLibationFixup;
public bool Downsample => config.AllowLibationFixup && config.LameDownsampleMono; public bool Downsample => Config.AllowLibationFixup && Config.LameDownsampleMono;
public bool MatchSourceBitrate => config.AllowLibationFixup && config.LameMatchSourceBR && config.LameTargetBitrate; public bool MatchSourceBitrate => Config.AllowLibationFixup && Config.LameMatchSourceBR && Config.LameTargetBitrate;
public bool MoveMoovToBeginning => config.MoveMoovToBeginning; public bool MoveMoovToBeginning => Config.MoveMoovToBeginning;
public AAXClean.FileType? InputType { get; init; } public AAXClean.FileType? InputType { get; init; }
public AudibleApi.Common.DrmType DrmType { get; init; } public AudibleApi.Common.DrmType DrmType { get; init; }
public AudibleApi.Common.ContentMetadata ContentMetadata { get; init; } public AudibleApi.Common.ContentMetadata ContentMetadata { get; init; }
@ -59,7 +59,7 @@ namespace FileLiberator
{ {
if (DownloadClipsBookmarks) if (DownloadClipsBookmarks)
{ {
var format = config.ClipsBookmarksFileFormat; var format = Config.ClipsBookmarksFileFormat;
var formatExtension = format.ToString().ToLowerInvariant(); var formatExtension = format.ToString().ToLowerInvariant();
var filePath = Path.ChangeExtension(fileName, formatExtension); var filePath = Path.ChangeExtension(fileName, formatExtension);
@ -84,7 +84,7 @@ namespace FileLiberator
return string.Empty; return string.Empty;
} }
private readonly Configuration config; public Configuration Config { get; }
private readonly IDisposable cancellation; private readonly IDisposable cancellation;
public void Dispose() public void Dispose()
{ {
@ -94,7 +94,7 @@ namespace FileLiberator
private DownloadOptions(Configuration config, LibraryBook libraryBook, [System.Diagnostics.CodeAnalysis.NotNull] string downloadUrl) private DownloadOptions(Configuration config, LibraryBook libraryBook, [System.Diagnostics.CodeAnalysis.NotNull] string downloadUrl)
{ {
this.config = ArgumentValidator.EnsureNotNull(config, nameof(config)); Config = ArgumentValidator.EnsureNotNull(config, nameof(config));
LibraryBook = ArgumentValidator.EnsureNotNull(libraryBook, nameof(libraryBook)); LibraryBook = ArgumentValidator.EnsureNotNull(libraryBook, nameof(libraryBook));
DownloadUrl = ArgumentValidator.EnsureNotNullOrEmpty(downloadUrl, nameof(downloadUrl)); DownloadUrl = ArgumentValidator.EnsureNotNullOrEmpty(downloadUrl, nameof(downloadUrl));
// no null/empty check for key/iv. unencrypted files do not have them // no null/empty check for key/iv. unencrypted files do not have them