Abstracted Chapters class, adding chapter titles and end times. Updated references.

This commit is contained in:
Michael Bucari-Tovo 2021-06-16 16:03:41 -06:00
parent 6ed4eb34bd
commit ebfdd44142
4 changed files with 83 additions and 55 deletions

View File

@ -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<System.Xml.XmlNode>()
.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<System.Xml.XmlNode>()
.Where(childnode => childnode.Attributes["key"].Value == "title")
.Select(childnode => childnode.Attributes["value"].Value)
.FirstOrDefault();
AddChapter(new Chapter(startTime, endTime, chapterTitle));
}
}
}
}

View File

@ -98,7 +98,7 @@ namespace AaxDecrypter
{ {
tags = new Tags(inputFileName); tags = new Tags(inputFileName);
encodingInfo = new EncodingInfo(inputFileName); encodingInfo = new EncodingInfo(inputFileName);
chapters = new Chapters(inputFileName, tags.duration.TotalSeconds); chapters = new AAXChapters(inputFileName);
var defaultFilename = Path.Combine( var defaultFilename = Path.Combine(
Path.GetDirectoryName(inputFileName), Path.GetDirectoryName(inputFileName),
@ -278,9 +278,9 @@ namespace AaxDecrypter
public bool Step3_Chapterize() public bool Step3_Chapterize()
{ {
var str1 = ""; 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(); var ffmpegTags = tags.GenerateFfmpegTags();

View File

@ -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;
}
/// <summary>
/// Chapter start time, in seconds.
/// </summary>
public double StartTime { get; private set; }
/// <summary>
/// Chapter end time, in seconds.
/// </summary>
public double EndTime { get; private set; }
public string Title { get; private set; }
}
}

View File

@ -1,72 +1,33 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Dinah.Core.Diagnostics;
namespace AaxDecrypter namespace AaxDecrypter
{ {
public class Chapters public abstract class Chapters
{ {
private List<double> markers { get; } private List<Chapter> _chapterList = new();
public int Count => _chapterList.Count;
public double FirstChapterStart => markers[0]; public Chapter FirstChapter => _chapterList[0];
public double LastChapterStart => markers[markers.Count - 1]; public Chapter LastChapter => _chapterList[Count - 1];
public IEnumerable<Chapter> ChapterList => _chapterList.AsEnumerable();
public Chapters(string file, double totalTime) public IEnumerable<TimeSpan> GetBeginningTimes() => ChapterList.Select(c => TimeSpan.FromSeconds(c.StartTime));
protected void AddChapter(Chapter chapter)
{ {
markers = getAAXChapters(file); _chapterList.Add(chapter);
// add end time
markers.Add(totalTime);
} }
private static List<double> 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<System.Xml.XmlNode>()
.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<TimeSpan> GetBeginningTimes()
{
for (var i = 0; i < Count; i++)
yield return TimeSpan.FromSeconds(markers[i]);
}
public string GenerateFfmpegChapters() public string GenerateFfmpegChapters()
{ {
var stringBuilder = new StringBuilder(); 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("[CHAPTER]\n");
stringBuilder.Append("TIMEBASE=1/1000\n"); stringBuilder.Append("TIMEBASE=1/1000\n");
stringBuilder.Append("START=" + start + "\n"); stringBuilder.Append("START=" + c.StartTime * 1000 + "\n");
stringBuilder.Append("END=" + end + "\n"); stringBuilder.Append("END=" + c.EndTime * 1000 + "\n");
stringBuilder.Append("title=" + chapterName + "\n"); stringBuilder.Append("title=" + c.Title + "\n");
} }
return stringBuilder.ToString(); return stringBuilder.ToString();