diff --git a/AaxDecrypter/AaxcDownloadConverter.cs b/AaxDecrypter/AaxcDownloadConverter.cs index 7ba1f3a3..89d624c8 100644 --- a/AaxDecrypter/AaxcDownloadConverter.cs +++ b/AaxDecrypter/AaxcDownloadConverter.cs @@ -135,9 +135,11 @@ namespace AaxDecrypter var aaxcProcesser = new FFMpegAaxcProcesser(downloadLicense); aaxcProcesser.ProgressUpdate += AaxcProcesser_ProgressUpdate; + bool userSuppliedChapters = chapters != null; + string metadataPath = null; - if (chapters != null) + if (userSuppliedChapters) { //Only write chaopters to the metadata file. All other aaxc metadata will be //wiped out but is restored in Step 3. @@ -151,7 +153,10 @@ namespace AaxDecrypter .GetAwaiter() .GetResult(); - if (chapters != null) + if (!userSuppliedChapters && aaxcProcesser.Succeeded) + chapters = new ChapterInfo(outputFileName); + + if (userSuppliedChapters) FileExt.SafeDelete(metadataPath); DecryptProgressUpdate?.Invoke(this, 0); @@ -187,6 +192,7 @@ namespace AaxDecrypter destTags.SetData(stag.BoxType, stag.Children.Cast().ToArray()); } outFile.Save(); + return true; } diff --git a/AaxDecrypter/Chapters.cs b/AaxDecrypter/Chapters.cs index 07ff0202..83d0f117 100644 --- a/AaxDecrypter/Chapters.cs +++ b/AaxDecrypter/Chapters.cs @@ -1,5 +1,8 @@ using Dinah.Core; +using Dinah.Core.Diagnostics; using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; using System.Linq; using System.Text; @@ -10,6 +13,37 @@ namespace AaxDecrypter private List _chapterList = new List(); public IEnumerable Chapters => _chapterList.AsEnumerable(); public int Count => _chapterList.Count; + + public ChapterInfo() { } + public ChapterInfo(string audiobookFile) + { + var info = new ProcessStartInfo + { + FileName = DecryptSupportLibraries.ffprobePath, + Arguments = "-loglevel panic -show_chapters -print_format xml \"" + audiobookFile + "\"" + }; + var xml = info.RunHidden().Output; + + var xmlDocument = new System.Xml.XmlDocument(); + xmlDocument.LoadXml(xml); + var chaptersXml = xmlDocument.SelectNodes("/ffprobe/chapters/chapter") + .Cast() + .Where(n => n.Name == "chapter"); + + foreach (var cnode in chaptersXml) + { + double startTime = double.Parse(cnode.Attributes["start_time"].Value.Replace(",", "."), CultureInfo.InvariantCulture); + double endTime = double.Parse(cnode.Attributes["end_time"].Value.Replace(",", "."), CultureInfo.InvariantCulture); + + string chapterTitle = cnode.ChildNodes + .Cast() + .Where(childnode => childnode.Attributes["key"].Value == "title") + .Select(childnode => childnode.Attributes["value"].Value) + .FirstOrDefault(); + + AddChapter(new Chapter(chapterTitle, (long)(startTime * 1000), (long)((endTime - startTime) * 1000))); + } + } public void AddChapter(Chapter chapter) { ArgumentValidator.EnsureNotNull(chapter, nameof(chapter));