From ebfdd44142ed61add1aa1c4e460647d610f34d15 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Wed, 16 Jun 2021 16:03:41 -0600 Subject: [PATCH] Abstracted Chapters class, adding chapter titles and end times. Updated references. --- AaxDecrypter/UNTESTED/AAXChapters.cs | 40 +++++++++++++ AaxDecrypter/UNTESTED/AaxToM4bConverter.cs | 6 +- AaxDecrypter/UNTESTED/Chapter.cs | 27 +++++++++ AaxDecrypter/UNTESTED/Chapters.cs | 65 +++++----------------- 4 files changed, 83 insertions(+), 55 deletions(-) create mode 100644 AaxDecrypter/UNTESTED/AAXChapters.cs create mode 100644 AaxDecrypter/UNTESTED/Chapter.cs diff --git a/AaxDecrypter/UNTESTED/AAXChapters.cs b/AaxDecrypter/UNTESTED/AAXChapters.cs new file mode 100644 index 00000000..f9770e87 --- /dev/null +++ b/AaxDecrypter/UNTESTED/AAXChapters.cs @@ -0,0 +1,40 @@ +using System.Diagnostics; +using System.Globalization; +using System.Linq; +using Dinah.Core.Diagnostics; + +namespace AaxDecrypter +{ + public class AAXChapters : Chapters + { + public AAXChapters(string file) + { + var info = new ProcessStartInfo + { + FileName = DecryptSupportLibraries.ffprobePath, + Arguments = "-loglevel panic -show_chapters -print_format xml \"" + file + "\"" + }; + 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(startTime, endTime, chapterTitle)); + } + } + } +} diff --git a/AaxDecrypter/UNTESTED/AaxToM4bConverter.cs b/AaxDecrypter/UNTESTED/AaxToM4bConverter.cs index c1b00d11..cbce511f 100644 --- a/AaxDecrypter/UNTESTED/AaxToM4bConverter.cs +++ b/AaxDecrypter/UNTESTED/AaxToM4bConverter.cs @@ -98,7 +98,7 @@ namespace AaxDecrypter { tags = new Tags(inputFileName); encodingInfo = new EncodingInfo(inputFileName); - chapters = new Chapters(inputFileName, tags.duration.TotalSeconds); + chapters = new AAXChapters(inputFileName); var defaultFilename = Path.Combine( Path.GetDirectoryName(inputFileName), @@ -278,9 +278,9 @@ namespace AaxDecrypter public bool Step3_Chapterize() { var str1 = ""; - if (chapters.FirstChapterStart != 0.0) + if (chapters.FirstChapter.StartTime != 0.0) { - str1 = " -ss " + chapters.FirstChapterStart.ToString("0.000", CultureInfo.InvariantCulture) + " -t " + (chapters.LastChapterStart - 1.0).ToString("0.000", CultureInfo.InvariantCulture) + " "; + str1 = " -ss " + chapters.FirstChapter.StartTime.ToString("0.000", CultureInfo.InvariantCulture) + " -t " + chapters.LastChapter.EndTime.ToString("0.000", CultureInfo.InvariantCulture) + " "; } var ffmpegTags = tags.GenerateFfmpegTags(); diff --git a/AaxDecrypter/UNTESTED/Chapter.cs b/AaxDecrypter/UNTESTED/Chapter.cs new file mode 100644 index 00000000..b4507d43 --- /dev/null +++ b/AaxDecrypter/UNTESTED/Chapter.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AaxDecrypter +{ + public class Chapter + { + public Chapter(double startTime, double endTime, string title) + { + StartTime = startTime; + EndTime = endTime; + Title = title; + } + /// + /// Chapter start time, in seconds. + /// + public double StartTime { get; private set; } + /// + /// Chapter end time, in seconds. + /// + public double EndTime { get; private set; } + public string Title { get; private set; } + } +} diff --git a/AaxDecrypter/UNTESTED/Chapters.cs b/AaxDecrypter/UNTESTED/Chapters.cs index d83ef3f2..10487915 100644 --- a/AaxDecrypter/UNTESTED/Chapters.cs +++ b/AaxDecrypter/UNTESTED/Chapters.cs @@ -1,72 +1,33 @@ using System; using System.Collections.Generic; -using System.Diagnostics; -using System.Globalization; using System.Linq; using System.Text; -using Dinah.Core.Diagnostics; namespace AaxDecrypter { - public class Chapters + public abstract class Chapters { - private List markers { get; } - - public double FirstChapterStart => markers[0]; - public double LastChapterStart => markers[markers.Count - 1]; - - public Chapters(string file, double totalTime) + private List _chapterList = new(); + public int Count => _chapterList.Count; + public Chapter FirstChapter => _chapterList[0]; + public Chapter LastChapter => _chapterList[Count - 1]; + public IEnumerable ChapterList => _chapterList.AsEnumerable(); + public IEnumerable GetBeginningTimes() => ChapterList.Select(c => TimeSpan.FromSeconds(c.StartTime)); + protected void AddChapter(Chapter chapter) { - markers = getAAXChapters(file); - - // add end time - markers.Add(totalTime); + _chapterList.Add(chapter); } - - private static List getAAXChapters(string file) - { - var info = new ProcessStartInfo - { - FileName = DecryptSupportLibraries.ffprobePath, - Arguments = "-loglevel panic -show_chapters -print_format xml \"" + file + "\"" - }; - var xml = info.RunHidden().Output; - - var xmlDocument = new System.Xml.XmlDocument(); - xmlDocument.LoadXml(xml); - var chapters = xmlDocument.SelectNodes("/ffprobe/chapters/chapter") - .Cast() - .Select(xmlNode => double.Parse(xmlNode.Attributes["start_time"].Value.Replace(",", "."), CultureInfo.InvariantCulture)) - .ToList(); - return chapters; - } - - // subtract 1 b/c end time marker is a real entry but isn't a real chapter. ie: fencepost - public int Count => markers.Count - 1; - - public IEnumerable GetBeginningTimes() - { - for (var i = 0; i < Count; i++) - yield return TimeSpan.FromSeconds(markers[i]); - } - public string GenerateFfmpegChapters() { var stringBuilder = new StringBuilder(); - for (var i = 0; i < Count; i++) + foreach (Chapter c in ChapterList) { - var chapter = i + 1; - - var start = markers[i] * 1000.0; - var end = markers[i + 1] * 1000.0; - var chapterName = chapter.ToString("D3"); - stringBuilder.Append("[CHAPTER]\n"); stringBuilder.Append("TIMEBASE=1/1000\n"); - stringBuilder.Append("START=" + start + "\n"); - stringBuilder.Append("END=" + end + "\n"); - stringBuilder.Append("title=" + chapterName + "\n"); + stringBuilder.Append("START=" + c.StartTime * 1000 + "\n"); + stringBuilder.Append("END=" + c.EndTime * 1000 + "\n"); + stringBuilder.Append("title=" + c.Title + "\n"); } return stringBuilder.ToString();