mirror of
https://github.com/rmcrackan/Libation.git
synced 2026-03-30 12:53:45 -04:00
Make fields readonly Remove unnecessary casts Format document Remove unnecessary usings Sort usings Use file-level namespaces Order modifiers
120 lines
3.7 KiB
C#
120 lines
3.7 KiB
C#
using AAXClean;
|
|
using AAXClean.Codecs;
|
|
using FileManager;
|
|
using Mpeg4Lib;
|
|
using System;
|
|
using System.IO;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace AaxDecrypter;
|
|
|
|
public class AaxcDownloadMultiConverter : AaxcDownloadConvertBase
|
|
{
|
|
private static readonly TimeSpan minChapterLength = TimeSpan.FromSeconds(3);
|
|
private FileStream? workingFileStream;
|
|
|
|
public AaxcDownloadMultiConverter(string outDirectory, string cacheDirectory, IDownloadOptions dlOptions)
|
|
: base(outDirectory, cacheDirectory, dlOptions)
|
|
{
|
|
AsyncSteps.Name = $"Download, Convert Aaxc To {DownloadOptions.OutputFormat}, and Split";
|
|
AsyncSteps["Step 1: Get Aaxc Metadata"] = () => Task.Run(Step_GetMetadata);
|
|
AsyncSteps["Step 2: Download Decrypted Audiobook"] = Step_DownloadAndDecryptAudiobookAsync;
|
|
}
|
|
|
|
protected override void OnInitialized()
|
|
{
|
|
//Finishing configuring lame encoder.
|
|
if (DownloadOptions.OutputFormat == OutputFormat.Mp3)
|
|
{
|
|
if (AaxFile is null)
|
|
throw new InvalidOperationException($"AaxFile is null during {nameof(OnInitialized)} in {nameof(AaxcDownloadConvertBase)}.");
|
|
if (DownloadOptions.LameConfig is null)
|
|
throw new InvalidOperationException($"LameConfig is null during {nameof(OnInitialized)} in {nameof(DownloadOptions)}.");
|
|
|
|
MpegUtil.ConfigureLameOptions(
|
|
AaxFile,
|
|
DownloadOptions.LameConfig,
|
|
DownloadOptions.Downsample,
|
|
DownloadOptions.MatchSourceBitrate,
|
|
chapters: null);
|
|
}
|
|
}
|
|
|
|
|
|
protected override async Task<bool> Step_DownloadAndDecryptAudiobookAsync()
|
|
{
|
|
if (AaxFile is null) return false;
|
|
|
|
try
|
|
{
|
|
await (AaxConversion = decryptMultiAsync(AaxFile, DownloadOptions.ChapterInfo));
|
|
|
|
if (AaxConversion.IsCompletedSuccessfully)
|
|
await moveMoovToBeginning(AaxFile, workingFileStream?.Name);
|
|
|
|
return AaxConversion.IsCompletedSuccessfully;
|
|
}
|
|
finally
|
|
{
|
|
workingFileStream?.Dispose();
|
|
FinalizeDownload();
|
|
}
|
|
}
|
|
|
|
private Mp4Operation decryptMultiAsync(Mp4File aaxFile, ChapterInfo splitChapters)
|
|
{
|
|
var chapterCount = 0;
|
|
return
|
|
DownloadOptions.OutputFormat == OutputFormat.M4b
|
|
? aaxFile.ConvertToMultiMp4aAsync
|
|
(
|
|
splitChapters,
|
|
newSplitCallback => newSplit(++chapterCount, splitChapters, newSplitCallback)
|
|
)
|
|
: aaxFile.ConvertToMultiMp3Async
|
|
(
|
|
splitChapters,
|
|
newSplitCallback => newSplit(++chapterCount, splitChapters, newSplitCallback),
|
|
DownloadOptions.LameConfig
|
|
);
|
|
|
|
void newSplit(int currentChapter, ChapterInfo splitChapters, INewSplitCallback newSplitCallback)
|
|
{
|
|
moveMoovToBeginning(aaxFile, workingFileStream?.Name).GetAwaiter().GetResult();
|
|
var newTempFile = GetNewTempFilePath(DownloadOptions.OutputFormat.ToString());
|
|
MultiConvertFileProperties props = new()
|
|
{
|
|
OutputFileName = newTempFile.FilePath,
|
|
PartsPosition = currentChapter,
|
|
PartsTotal = splitChapters.Count,
|
|
Title = newSplitCallback.Chapter?.Title,
|
|
};
|
|
|
|
newSplitCallback.OutputFile = workingFileStream = createOutputFileStream(props);
|
|
newSplitCallback.TrackTitle = DownloadOptions.GetMultipartTitle(props);
|
|
newSplitCallback.TrackNumber = currentChapter;
|
|
newSplitCallback.TrackCount = splitChapters.Count;
|
|
|
|
OnTempFileCreated(newTempFile with { PartProperties = props });
|
|
}
|
|
|
|
FileStream createOutputFileStream(MultiConvertFileProperties multiConvertFileProperties)
|
|
{
|
|
FileUtility.SaferDelete(multiConvertFileProperties.OutputFileName);
|
|
return File.Open(multiConvertFileProperties.OutputFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
|
|
}
|
|
}
|
|
|
|
private Mp4Operation moveMoovToBeginning(Mp4File aaxFile, string? filename)
|
|
{
|
|
if (DownloadOptions.OutputFormat is OutputFormat.M4b
|
|
&& DownloadOptions.MoveMoovToBeginning
|
|
&& filename is not null
|
|
&& File.Exists(filename))
|
|
{
|
|
return Mp4File.RelocateMoovAsync(filename);
|
|
}
|
|
else return Mp4Operation.FromCompleted(aaxFile);
|
|
}
|
|
}
|