Moved Taglib loading into the step sequence and added event and method to request cover art.

This commit is contained in:
Michael Bucari-Tovo 2021-06-30 17:31:01 -06:00
parent aa3c648c4c
commit 8d6b304a8b

View File

@ -10,51 +10,53 @@ using System.Threading.Tasks;
namespace AaxDecrypter namespace AaxDecrypter
{ {
public interface ISimpleAaxToM4bConverter public interface ISimpleAaxcToM4bConverter
{ {
event EventHandler<AaxcTagLibFile> RetrievedTags;
event EventHandler<byte[]> RetrievedCoverArt;
event EventHandler<TimeSpan> DecryptTimeRemaining;
event EventHandler<int> DecryptProgressUpdate; event EventHandler<int> DecryptProgressUpdate;
bool Run(); bool Run();
string AppName { get; set; } string AppName { get; set; }
string outDir { get; } string outDir { get; }
string outputFileName { get; } string outputFileName { get; }
ChapterInfo chapters { get; } ChapterInfo chapters { get; }
AaxcTagLibFile aaxcTagLib { get; }
byte[] coverArt { get; }
void SetCoverArt(byte[] coverArt);
void SetOutputFilename(string outFileName); void SetOutputFilename(string outFileName);
string Title { get; }
string Author { get; }
string Narrator { get; }
byte[] CoverArt { get; }
} }
public interface IAdvancedAaxcToM4bConverter : ISimpleAaxToM4bConverter public interface IAdvancedAaxcToM4bConverter : ISimpleAaxcToM4bConverter
{ {
void Cancel(); void Cancel();
bool Step1_CreateDir(); bool Step1_CreateDir();
bool Step2_DownloadAndCombine(); bool Step2_GetMetadata();
bool Step3_RestoreMetadata(); bool Step3_DownloadAndCombine();
bool Step4_CreateCue(); bool Step4_RestoreMetadata();
bool Step5_CreateNfo(); bool Step5_CreateCue();
bool Step6_CreateNfo();
} }
public class AaxcDownloadConverter : IAdvancedAaxcToM4bConverter public class AaxcDownloadConverter : IAdvancedAaxcToM4bConverter
{ {
public event EventHandler<AaxcTagLibFile> RetrievedTags;
public event EventHandler<byte[]> RetrievedCoverArt;
public event EventHandler<int> DecryptProgressUpdate; public event EventHandler<int> DecryptProgressUpdate;
public event EventHandler<TimeSpan> DecryptTimeRemaining; public event EventHandler<TimeSpan> DecryptTimeRemaining;
public string AppName { get; set; } = nameof(AaxcDownloadConverter); public string AppName { get; set; } = nameof(AaxcDownloadConverter);
public string outDir { get; private set; } public string outDir { get; private set; }
public string outputFileName { get; private set; } public string outputFileName { get; private set; }
public ChapterInfo chapters { get; private set; } public ChapterInfo chapters { get; private set; }
public string Title => aaxcTagLib.TitleSansUnabridged; public AaxcTagLibFile aaxcTagLib { get; private set; }
public string Author => aaxcTagLib.FirstAuthor ?? "[unknown]"; public byte[] coverArt { get; private set; }
public string Narrator => aaxcTagLib.Narrator ?? "[unknown]";
public byte[] CoverArt => aaxcTagLib.AppleTags.Pictures.Length > 0 ? aaxcTagLib.Tag.Pictures[0].Data.Data : default;
private AaxcTagLibFile aaxcTagLib { get; set; }
private StepSequence steps { get; } private StepSequence steps { get; }
private DownloadLicense downloadLicense { get; set; } private DownloadLicense downloadLicense { get; set; }
private FFMpegAaxcProcesser aaxcProcesser; private FFMpegAaxcProcesser aaxcProcesser;
public static async Task<AaxcDownloadConverter> CreateAsync(string outDirectory, DownloadLicense dlLic, ChapterInfo chapters = null) public static AaxcDownloadConverter Create(string outDirectory, DownloadLicense dlLic, ChapterInfo chapters = null)
{ {
var converter = new AaxcDownloadConverter(outDirectory, dlLic, chapters); var converter = new AaxcDownloadConverter(outDirectory, dlLic, chapters);
await converter.prelimProcessing(); converter.SetOutputFilename(Path.GetTempFileName());
return converter; return converter;
} }
@ -72,35 +74,17 @@ namespace AaxDecrypter
Name = "Convert Aax To M4b", Name = "Convert Aax To M4b",
["Step 1: Create Dir"] = Step1_CreateDir, ["Step 1: Create Dir"] = Step1_CreateDir,
["Step 2: Download and Combine Audiobook"] = Step2_DownloadAndCombine, ["Step 2: Get Aaxc Metadata"] = Step2_GetMetadata,
["Step 3: Restore Aaxc Metadata"] = Step3_RestoreMetadata, ["Step 3: Download Decrypted Audiobook"] = Step3_DownloadAndCombine,
["Step 4: Create Cue"] = Step4_CreateCue, ["Step 4: Restore Aaxc Metadata"] = Step4_RestoreMetadata,
["Step 5: Create Nfo"] = Step5_CreateNfo, ["Step 5: Create Cue"] = Step5_CreateCue,
["Step 6: Create Nfo"] = Step6_CreateNfo,
}; };
downloadLicense = dlLic; downloadLicense = dlLic;
this.chapters = chapters; this.chapters = chapters;
} }
private async Task prelimProcessing()
{
//Get metadata from the file over http
var client = new System.Net.Http.HttpClient();
client.DefaultRequestHeaders.Add("User-Agent", downloadLicense.UserAgent);
var networkFile = await NetworkFileAbstraction.CreateAsync(client, new Uri(downloadLicense.DownloadUrl));
aaxcTagLib = await Task.Run(() => new AaxcTagLibFile(networkFile));
var defaultFilename = Path.Combine(
outDir,
PathLib.ToPathSafeString(aaxcTagLib.FirstAuthor ?? "[unknown]"),
PathLib.ToPathSafeString(aaxcTagLib.TitleSansUnabridged) + ".m4b"
);
SetOutputFilename(defaultFilename);
}
public void SetOutputFilename(string outFileName) public void SetOutputFilename(string outFileName)
{ {
outputFileName = PathLib.ReplaceExtension(outFileName, ".m4b"); outputFileName = PathLib.ReplaceExtension(outFileName, ".m4b");
@ -110,6 +94,14 @@ namespace AaxDecrypter
File.Delete(outputFileName); File.Delete(outputFileName);
} }
public void SetCoverArt(byte[] coverArt)
{
if (coverArt is null) return;
this.coverArt = coverArt;
RetrievedCoverArt?.Invoke(this, coverArt);
}
public bool Run() public bool Run()
{ {
var (IsSuccess, Elapsed) = steps.Run(); var (IsSuccess, Elapsed) = steps.Run();
@ -134,7 +126,27 @@ namespace AaxDecrypter
return true; return true;
} }
public bool Step2_DownloadAndCombine() public bool Step2_GetMetadata()
{
//Get metadata from the file over http
var client = new System.Net.Http.HttpClient();
client.DefaultRequestHeaders.Add("User-Agent", downloadLicense.UserAgent);
var networkFile = NetworkFileAbstraction.CreateAsync(client, new Uri(downloadLicense.DownloadUrl)).GetAwaiter().GetResult();
aaxcTagLib = new AaxcTagLibFile(networkFile);
if (coverArt is null && aaxcTagLib.AppleTags.Pictures.Length > 0)
{
coverArt = aaxcTagLib.AppleTags.Pictures[0].Data.Data;
}
RetrievedTags?.Invoke(this, aaxcTagLib);
RetrievedCoverArt?.Invoke(this, coverArt);
return true;
}
public bool Step3_DownloadAndCombine()
{ {
aaxcProcesser = new FFMpegAaxcProcesser(downloadLicense); aaxcProcesser = new FFMpegAaxcProcesser(downloadLicense);
aaxcProcesser.ProgressUpdate += AaxcProcesser_ProgressUpdate; aaxcProcesser.ProgressUpdate += AaxcProcesser_ProgressUpdate;
@ -184,22 +196,28 @@ namespace AaxDecrypter
/// <summary> /// <summary>
/// Copy all aacx metadata to m4b file, including cover art. /// Copy all aacx metadata to m4b file, including cover art.
/// </summary> /// </summary>
public bool Step3_RestoreMetadata() public bool Step4_RestoreMetadata()
{ {
var outFile = new AaxcTagLibFile(outputFileName); var outFile = new AaxcTagLibFile(outputFileName);
outFile.CopyTagsFrom(aaxcTagLib); outFile.CopyTagsFrom(aaxcTagLib);
if (outFile.AppleTags.Pictures.Length == 0 && coverArt is not null)
{
outFile.AddPicture(coverArt);
}
outFile.Save(); outFile.Save();
return true; return true;
} }
public bool Step4_CreateCue() public bool Step5_CreateCue()
{ {
File.WriteAllText(PathLib.ReplaceExtension(outputFileName, ".cue"), Cue.CreateContents(Path.GetFileName(outputFileName), chapters)); File.WriteAllText(PathLib.ReplaceExtension(outputFileName, ".cue"), Cue.CreateContents(Path.GetFileName(outputFileName), chapters));
return true; return true;
} }
public bool Step5_CreateNfo() public bool Step6_CreateNfo()
{ {
File.WriteAllText(PathLib.ReplaceExtension(outputFileName, ".nfo"), NFO.CreateContents(AppName, aaxcTagLib, chapters)); File.WriteAllText(PathLib.ReplaceExtension(outputFileName, ".nfo"), NFO.CreateContents(AppName, aaxcTagLib, chapters));
return true; return true;