Merge pull request #305 from Mbucari/master
Fix some bugs with user settings.
This commit is contained in:
commit
7364700899
@ -34,27 +34,12 @@ namespace AaxDecrypter
|
|||||||
|
|
||||||
//Finishing configuring lame encoder.
|
//Finishing configuring lame encoder.
|
||||||
if (DownloadOptions.OutputFormat == OutputFormat.Mp3)
|
if (DownloadOptions.OutputFormat == OutputFormat.Mp3)
|
||||||
{
|
MpegUtil.ConfigureLameOptions(
|
||||||
double bitrateMultiple = 1;
|
AaxFile,
|
||||||
|
DownloadOptions.LameConfig,
|
||||||
|
DownloadOptions.Downsample,
|
||||||
|
DownloadOptions.MatchSourceBitrate);
|
||||||
|
|
||||||
if (AaxFile.AudioChannels == 2)
|
|
||||||
{
|
|
||||||
if (DownloadOptions.Downsample)
|
|
||||||
bitrateMultiple = 0.5;
|
|
||||||
else
|
|
||||||
DownloadOptions.LameConfig.Mode = NAudio.Lame.MPEGMode.Stereo;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DownloadOptions.MatchSourceBitrate)
|
|
||||||
{
|
|
||||||
int kbps = (int)(AaxFile.AverageBitrate * bitrateMultiple / 1024);
|
|
||||||
|
|
||||||
if (DownloadOptions.LameConfig.VBR is null)
|
|
||||||
DownloadOptions.LameConfig.BitRate = kbps;
|
|
||||||
else if (DownloadOptions.LameConfig.VBR == NAudio.Lame.VBRMode.ABR)
|
|
||||||
DownloadOptions.LameConfig.ABRRateKbps = kbps;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OnRetrievedTitle(AaxFile.AppleTags.TitleSansUnabridged);
|
OnRetrievedTitle(AaxFile.AppleTags.TitleSansUnabridged);
|
||||||
OnRetrievedAuthors(AaxFile.AppleTags.FirstAuthor ?? "[unknown]");
|
OnRetrievedAuthors(AaxFile.AppleTags.FirstAuthor ?? "[unknown]");
|
||||||
|
|||||||
@ -78,13 +78,10 @@ namespace AaxDecrypter
|
|||||||
OnFileCreated(OutputFileName);
|
OnFileCreated(OutputFileName);
|
||||||
|
|
||||||
AaxFile.ConversionProgressUpdate += AaxFile_ConversionProgressUpdate;
|
AaxFile.ConversionProgressUpdate += AaxFile_ConversionProgressUpdate;
|
||||||
var decryptionResult
|
|
||||||
= DownloadOptions.OutputFormat == OutputFormat.M4b
|
|
||||||
? await AaxFile.ConvertToMp4aAsync(outputFile, DownloadOptions.ChapterInfo, DownloadOptions.TrimOutputToChapterLength)
|
|
||||||
: await AaxFile.ConvertToMp3Async(outputFile, DownloadOptions.LameConfig, DownloadOptions.ChapterInfo, DownloadOptions.TrimOutputToChapterLength);
|
|
||||||
AaxFile.ConversionProgressUpdate -= AaxFile_ConversionProgressUpdate;
|
|
||||||
|
|
||||||
DownloadOptions.ChapterInfo = AaxFile.Chapters;
|
ConversionResult decryptionResult = await decryptAsync(outputFile);
|
||||||
|
|
||||||
|
AaxFile.ConversionProgressUpdate -= AaxFile_ConversionProgressUpdate;
|
||||||
|
|
||||||
Step_DownloadAudiobook_End(zeroProgress);
|
Step_DownloadAudiobook_End(zeroProgress);
|
||||||
|
|
||||||
@ -94,5 +91,23 @@ namespace AaxDecrypter
|
|||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Task<ConversionResult> decryptAsync(Stream outputFile)
|
||||||
|
=> DownloadOptions.OutputFormat == OutputFormat.Mp3 ?
|
||||||
|
AaxFile.ConvertToMp3Async
|
||||||
|
(
|
||||||
|
outputFile,
|
||||||
|
DownloadOptions.LameConfig,
|
||||||
|
DownloadOptions.ChapterInfo,
|
||||||
|
DownloadOptions.TrimOutputToChapterLength
|
||||||
|
)
|
||||||
|
: DownloadOptions.FixupFile ?
|
||||||
|
AaxFile.ConvertToMp4aAsync
|
||||||
|
(
|
||||||
|
outputFile,
|
||||||
|
DownloadOptions.ChapterInfo,
|
||||||
|
DownloadOptions.TrimOutputToChapterLength
|
||||||
|
)
|
||||||
|
: AaxFile.ConvertToMp4aAsync(outputFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,10 +14,11 @@ namespace AaxDecrypter
|
|||||||
bool RetainEncryptedFile { get; }
|
bool RetainEncryptedFile { get; }
|
||||||
bool StripUnabridged { get; }
|
bool StripUnabridged { get; }
|
||||||
bool CreateCueSheet { get; }
|
bool CreateCueSheet { get; }
|
||||||
ChapterInfo ChapterInfo { get; set; }
|
ChapterInfo ChapterInfo { get; }
|
||||||
NAudio.Lame.LameConfig LameConfig { get; set; }
|
bool FixupFile { get; }
|
||||||
bool Downsample { get; set; }
|
NAudio.Lame.LameConfig LameConfig { get; }
|
||||||
bool MatchSourceBitrate { get; set; }
|
bool Downsample { get; }
|
||||||
|
bool MatchSourceBitrate { get; }
|
||||||
string GetMultipartFileName(MultiConvertFileProperties props);
|
string GetMultipartFileName(MultiConvertFileProperties props);
|
||||||
string GetMultipartTitleName(MultiConvertFileProperties props);
|
string GetMultipartTitleName(MultiConvertFileProperties props);
|
||||||
}
|
}
|
||||||
|
|||||||
33
Source/AaxDecrypter/MpegUtil.cs
Normal file
33
Source/AaxDecrypter/MpegUtil.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
using AAXClean;
|
||||||
|
using NAudio.Lame;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace AaxDecrypter
|
||||||
|
{
|
||||||
|
public static class MpegUtil
|
||||||
|
{
|
||||||
|
public static void ConfigureLameOptions(Mp4File mp4File, LameConfig lameConfig, bool downsample, bool matchSourceBitrate)
|
||||||
|
{
|
||||||
|
double bitrateMultiple = 1;
|
||||||
|
|
||||||
|
if (mp4File.AudioChannels == 2)
|
||||||
|
{
|
||||||
|
if (downsample)
|
||||||
|
bitrateMultiple = 0.5;
|
||||||
|
else
|
||||||
|
lameConfig.Mode = MPEGMode.Stereo;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matchSourceBitrate)
|
||||||
|
{
|
||||||
|
int kbps = (int)(mp4File.AverageBitrate * bitrateMultiple / 1024);
|
||||||
|
|
||||||
|
if (lameConfig.VBR is null)
|
||||||
|
lameConfig.BitRate = kbps;
|
||||||
|
else if (lameConfig.VBR == VBRMode.ABR)
|
||||||
|
lameConfig.ABRRateKbps = kbps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,7 +2,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0-windows</TargetFramework>
|
<TargetFramework>net6.0-windows</TargetFramework>
|
||||||
<Version>8.1.5.1</Version>
|
<Version>8.1.5.23</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Octokit" Version="0.51.0" />
|
<PackageReference Include="Octokit" Version="0.51.0" />
|
||||||
@ -18,6 +18,6 @@
|
|||||||
<DebugType>embedded</DebugType>
|
<DebugType>embedded</DebugType>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
|
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
|
||||||
<Exec Command="if $(Configuration) == Debug (
dotnet bump-version revision AppScaffolding.csproj
)" />
|
<Exec Command="if $(Configuration) == Debug (
dotnet tool restore
dotnet bump-version revision AppScaffolding.csproj
)" />
|
||||||
</Target>
|
</Target>
|
||||||
</Project>
|
</Project>
|
||||||
@ -53,8 +53,17 @@ namespace FileLiberator
|
|||||||
OnNarratorsDiscovered(m4bBook.AppleTags.Narrator);
|
OnNarratorsDiscovered(m4bBook.AppleTags.Narrator);
|
||||||
OnCoverImageDiscovered(m4bBook.AppleTags.Cover);
|
OnCoverImageDiscovered(m4bBook.AppleTags.Cover);
|
||||||
|
|
||||||
|
var config = Configuration.Instance;
|
||||||
|
var lameConfig = GetLameOptions(config);
|
||||||
|
|
||||||
|
//Finishing configuring lame encoder.
|
||||||
|
AaxDecrypter.MpegUtil.ConfigureLameOptions(
|
||||||
|
m4bBook,
|
||||||
|
lameConfig,
|
||||||
|
config.LameDownsampleMono,
|
||||||
|
config.LameMatchSourceBR);
|
||||||
|
|
||||||
using var mp3File = File.OpenWrite(Path.GetTempFileName());
|
using var mp3File = File.OpenWrite(Path.GetTempFileName());
|
||||||
var lameConfig = GetLameOptions(Configuration.Instance);
|
|
||||||
var result = await m4bBook.ConvertToMp3Async(mp3File, lameConfig);
|
var result = await m4bBook.ConvertToMp3Async(mp3File, lameConfig);
|
||||||
m4bBook.InputStream.Close();
|
m4bBook.InputStream.Close();
|
||||||
mp3File.Close();
|
mp3File.Close();
|
||||||
|
|||||||
@ -146,6 +146,9 @@ namespace FileLiberator
|
|||||||
var outputFormat = !encrypted || (config.AllowLibationFixup && config.DecryptToLossy) ?
|
var outputFormat = !encrypted || (config.AllowLibationFixup && config.DecryptToLossy) ?
|
||||||
OutputFormat.Mp3 : OutputFormat.M4b;
|
OutputFormat.Mp3 : OutputFormat.M4b;
|
||||||
|
|
||||||
|
long chapterStartMs = config.StripAudibleBrandAudio ?
|
||||||
|
contentLic.ContentMetadata.ChapterInfo.BrandIntroDurationMs : 0;
|
||||||
|
|
||||||
var dlOptions = new DownloadOptions
|
var dlOptions = new DownloadOptions
|
||||||
(
|
(
|
||||||
libraryBook,
|
libraryBook,
|
||||||
@ -162,7 +165,9 @@ namespace FileLiberator
|
|||||||
Downsample = config.AllowLibationFixup && config.LameDownsampleMono,
|
Downsample = config.AllowLibationFixup && config.LameDownsampleMono,
|
||||||
MatchSourceBitrate = config.AllowLibationFixup && config.LameMatchSourceBR && config.LameTargetBitrate,
|
MatchSourceBitrate = config.AllowLibationFixup && config.LameMatchSourceBR && config.LameTargetBitrate,
|
||||||
CreateCueSheet = config.CreateCueSheet,
|
CreateCueSheet = config.CreateCueSheet,
|
||||||
LameConfig = GetLameOptions(config)
|
LameConfig = GetLameOptions(config),
|
||||||
|
ChapterInfo = new AAXClean.ChapterInfo(TimeSpan.FromMilliseconds(chapterStartMs)),
|
||||||
|
FixupFile = config.AllowLibationFixup
|
||||||
};
|
};
|
||||||
|
|
||||||
var chapters = flattenChapters(contentLic.ContentMetadata.ChapterInfo.Chapters).OrderBy(c => c.StartOffsetMs).ToList();
|
var chapters = flattenChapters(contentLic.ContentMetadata.ChapterInfo.Chapters).OrderBy(c => c.StartOffsetMs).ToList();
|
||||||
@ -170,31 +175,98 @@ namespace FileLiberator
|
|||||||
if (config.MergeOpeningAndEndCredits)
|
if (config.MergeOpeningAndEndCredits)
|
||||||
combineCredits(chapters);
|
combineCredits(chapters);
|
||||||
|
|
||||||
if (config.AllowLibationFixup || outputFormat == OutputFormat.Mp3)
|
|
||||||
{
|
|
||||||
long startMs = dlOptions.TrimOutputToChapterLength ?
|
|
||||||
contentLic.ContentMetadata.ChapterInfo.BrandIntroDurationMs : 0;
|
|
||||||
|
|
||||||
dlOptions.ChapterInfo = new AAXClean.ChapterInfo(TimeSpan.FromMilliseconds(startMs));
|
|
||||||
|
|
||||||
for (int i = 0; i < chapters.Count; i++)
|
for (int i = 0; i < chapters.Count; i++)
|
||||||
{
|
{
|
||||||
var chapter = chapters[i];
|
var chapter = chapters[i];
|
||||||
long chapLenMs = chapter.LengthMs;
|
long chapLenMs = chapter.LengthMs;
|
||||||
|
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
chapLenMs -= startMs;
|
chapLenMs -= chapterStartMs;
|
||||||
|
|
||||||
if (config.StripAudibleBrandAudio && i == chapters.Count - 1)
|
if (config.StripAudibleBrandAudio && i == chapters.Count - 1)
|
||||||
chapLenMs -= contentLic.ContentMetadata.ChapterInfo.BrandOutroDurationMs;
|
chapLenMs -= contentLic.ContentMetadata.ChapterInfo.BrandOutroDurationMs;
|
||||||
|
|
||||||
dlOptions.ChapterInfo.AddChapter(chapter.Title, TimeSpan.FromMilliseconds(chapLenMs));
|
dlOptions.ChapterInfo.AddChapter(chapter.Title, TimeSpan.FromMilliseconds(chapLenMs));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return dlOptions;
|
return dlOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Flatten Audible's new hierarchical chapters, combining children into parents.
|
||||||
|
|
||||||
|
Audible may deliver chapters like this:
|
||||||
|
|
||||||
|
00:00 - 00:10 Opening Credits
|
||||||
|
00:10 - 00:12 Book 1
|
||||||
|
00:12 - 00:14 | Part 1
|
||||||
|
00:14 - 01:40 | | Chapter 1
|
||||||
|
01:40 - 03:20 | | Chapter 2
|
||||||
|
03:20 - 03:22 | Part 2
|
||||||
|
03:22 - 05:00 | | Chapter 3
|
||||||
|
05:00 - 06:40 | | Chapter 4
|
||||||
|
06:40 - 06:42 Book 2
|
||||||
|
06:42 - 06:44 | Part 3
|
||||||
|
06:44 - 08:20 | | Chapter 5
|
||||||
|
08:20 - 10:00 | | Chapter 6
|
||||||
|
10:00 - 10:02 | Part 4
|
||||||
|
10:02 - 11:40 | | Chapter 7
|
||||||
|
11:40 - 13:20 | | Chapter 8
|
||||||
|
13:20 - 13:30 End Credits
|
||||||
|
|
||||||
|
And flattenChapters will combine them into this:
|
||||||
|
|
||||||
|
00:00 - 00:10 Opening Credits
|
||||||
|
00:10 - 01:40 Book 1: Part 1: Chapter 1
|
||||||
|
01:40 - 03:20 Book 1: Part 1: Chapter 2
|
||||||
|
03:20 - 05:00 Book 1: Part 2: Chapter 3
|
||||||
|
05:00 - 06:40 Book 1: Part 2: Chapter 4
|
||||||
|
06:40 - 08:20 Book 2: Part 3: Chapter 5
|
||||||
|
08:20 - 10:00 Book 2: Part 3: Chapter 6
|
||||||
|
10:00 - 11:40 Book 2: Part 4: Chapter 7
|
||||||
|
11:40 - 13:20 Book 2: Part 4: Chapter 8
|
||||||
|
13:20 - 13:40 End Credits
|
||||||
|
|
||||||
|
However, if one of the parent chapters is longer than 10000 milliseconds, it's kept as its own
|
||||||
|
chapter. A duration longer than a few seconds implies that the chapter contains more than just
|
||||||
|
the narrator saying the chapter title, so it should probably be preserved as a separate chapter.
|
||||||
|
Using the example above, if "Book 1" was 15 seconds long and "Part 3" was 20 seconds long:
|
||||||
|
|
||||||
|
00:00 - 00:10 Opening Credits
|
||||||
|
00:10 - 00:25 Book 1
|
||||||
|
00:25 - 00:27 | Part 1
|
||||||
|
00:27 - 01:40 | | Chapter 1
|
||||||
|
01:40 - 03:20 | | Chapter 2
|
||||||
|
03:20 - 03:22 | Part 2
|
||||||
|
03:22 - 05:00 | | Chapter 3
|
||||||
|
05:00 - 06:40 | | Chapter 4
|
||||||
|
06:40 - 06:42 Book 2
|
||||||
|
06:42 - 07:02 | Part 3
|
||||||
|
07:02 - 08:20 | | Chapter 5
|
||||||
|
08:20 - 10:00 | | Chapter 6
|
||||||
|
10:00 - 10:02 | Part 4
|
||||||
|
10:02 - 11:40 | | Chapter 7
|
||||||
|
11:40 - 13:20 | | Chapter 8
|
||||||
|
13:20 - 13:30 End Credits
|
||||||
|
|
||||||
|
then flattenChapters will combine them into this:
|
||||||
|
|
||||||
|
00:00 - 00:10 Opening Credits
|
||||||
|
00:10 - 00:25 Book 1
|
||||||
|
00:25 - 01:40 Book 1: Part 1: Chapter 1
|
||||||
|
01:40 - 03:20 Book 1: Part 1: Chapter 2
|
||||||
|
03:20 - 05:00 Book 1: Part 2: Chapter 3
|
||||||
|
05:00 - 06:40 Book 1: Part 2: Chapter 4
|
||||||
|
06:40 - 07:02 Book 2: Part 3
|
||||||
|
07:02 - 08:20 Book 2: Part 3: Chapter 5
|
||||||
|
08:20 - 10:00 Book 2: Part 3: Chapter 6
|
||||||
|
10:00 - 11:40 Book 2: Part 4: Chapter 7
|
||||||
|
11:40 - 13:20 Book 2: Part 4: Chapter 8
|
||||||
|
13:20 - 13:40 End Credits
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
public static List<AudibleApi.Common.Chapter> flattenChapters(IList<AudibleApi.Common.Chapter> chapters, string titleConcat = ": ")
|
public static List<AudibleApi.Common.Chapter> flattenChapters(IList<AudibleApi.Common.Chapter> chapters, string titleConcat = ": ")
|
||||||
{
|
{
|
||||||
List<AudibleApi.Common.Chapter> chaps = new();
|
List<AudibleApi.Common.Chapter> chaps = new();
|
||||||
@ -202,10 +274,15 @@ namespace FileLiberator
|
|||||||
foreach (var c in chapters)
|
foreach (var c in chapters)
|
||||||
{
|
{
|
||||||
if (c.Chapters is not null)
|
if (c.Chapters is not null)
|
||||||
|
{
|
||||||
|
if (c.LengthMs < 10000)
|
||||||
{
|
{
|
||||||
c.Chapters[0].StartOffsetMs = c.StartOffsetMs;
|
c.Chapters[0].StartOffsetMs = c.StartOffsetMs;
|
||||||
c.Chapters[0].StartOffsetSec = c.StartOffsetSec;
|
c.Chapters[0].StartOffsetSec = c.StartOffsetSec;
|
||||||
c.Chapters[0].LengthMs += c.LengthMs;
|
c.Chapters[0].LengthMs += c.LengthMs;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
chaps.Add(c);
|
||||||
|
|
||||||
var children = flattenChapters(c.Chapters);
|
var children = flattenChapters(c.Chapters);
|
||||||
|
|
||||||
@ -213,6 +290,7 @@ namespace FileLiberator
|
|||||||
child.Title = $"{c.Title}{titleConcat}{child.Title}";
|
child.Title = $"{c.Title}{titleConcat}{child.Title}";
|
||||||
|
|
||||||
chaps.AddRange(children);
|
chaps.AddRange(children);
|
||||||
|
c.Chapters = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
chaps.Add(c);
|
chaps.Add(c);
|
||||||
|
|||||||
@ -20,10 +20,11 @@ namespace FileLiberator
|
|||||||
public bool RetainEncryptedFile { get; init; }
|
public bool RetainEncryptedFile { get; init; }
|
||||||
public bool StripUnabridged { get; init; }
|
public bool StripUnabridged { get; init; }
|
||||||
public bool CreateCueSheet { get; init; }
|
public bool CreateCueSheet { get; init; }
|
||||||
public ChapterInfo ChapterInfo { get; set; }
|
public ChapterInfo ChapterInfo { get; init; }
|
||||||
public NAudio.Lame.LameConfig LameConfig { get; set; }
|
public bool FixupFile { get; init; }
|
||||||
public bool Downsample { get; set; }
|
public NAudio.Lame.LameConfig LameConfig { get; init; }
|
||||||
public bool MatchSourceBitrate { get; set; }
|
public bool Downsample { get; init; }
|
||||||
|
public bool MatchSourceBitrate { get; init; }
|
||||||
public ReplacementCharacters ReplacementCharacters => Configuration.Instance.ReplacementCharacters;
|
public ReplacementCharacters ReplacementCharacters => Configuration.Instance.ReplacementCharacters;
|
||||||
|
|
||||||
public string GetMultipartFileName(MultiConvertFileProperties props)
|
public string GetMultipartFileName(MultiConvertFileProperties props)
|
||||||
|
|||||||
@ -43,6 +43,7 @@ namespace LibationWinForms.Dialogs
|
|||||||
LameMatchSourceBRCbox_CheckedChanged(this, EventArgs.Empty);
|
LameMatchSourceBRCbox_CheckedChanged(this, EventArgs.Empty);
|
||||||
convertFormatRb_CheckedChanged(this, EventArgs.Empty);
|
convertFormatRb_CheckedChanged(this, EventArgs.Empty);
|
||||||
allowLibationFixupCbox_CheckedChanged(this, EventArgs.Empty);
|
allowLibationFixupCbox_CheckedChanged(this, EventArgs.Empty);
|
||||||
|
splitFilesByChapterCbox_CheckedChanged(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Save_AudioSettings(Configuration config)
|
private void Save_AudioSettings(Configuration config)
|
||||||
@ -92,6 +93,7 @@ namespace LibationWinForms.Dialogs
|
|||||||
}
|
}
|
||||||
private void allowLibationFixupCbox_CheckedChanged(object sender, EventArgs e)
|
private void allowLibationFixupCbox_CheckedChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
audiobookFixupsGb.Enabled = allowLibationFixupCbox.Checked;
|
||||||
convertLosslessRb.Enabled = allowLibationFixupCbox.Checked;
|
convertLosslessRb.Enabled = allowLibationFixupCbox.Checked;
|
||||||
convertLossyRb.Enabled = allowLibationFixupCbox.Checked;
|
convertLossyRb.Enabled = allowLibationFixupCbox.Checked;
|
||||||
splitFilesByChapterCbox.Enabled = allowLibationFixupCbox.Checked;
|
splitFilesByChapterCbox.Enabled = allowLibationFixupCbox.Checked;
|
||||||
|
|||||||
@ -105,10 +105,11 @@
|
|||||||
this.lameTargetQualityRb = new System.Windows.Forms.RadioButton();
|
this.lameTargetQualityRb = new System.Windows.Forms.RadioButton();
|
||||||
this.lameTargetBitrateRb = new System.Windows.Forms.RadioButton();
|
this.lameTargetBitrateRb = new System.Windows.Forms.RadioButton();
|
||||||
this.stripUnabridgedCbox = new System.Windows.Forms.CheckBox();
|
this.stripUnabridgedCbox = new System.Windows.Forms.CheckBox();
|
||||||
|
this.mergeOpeningEndCreditsCbox = new System.Windows.Forms.CheckBox();
|
||||||
this.retainAaxFileCbox = new System.Windows.Forms.CheckBox();
|
this.retainAaxFileCbox = new System.Windows.Forms.CheckBox();
|
||||||
this.downloadCoverArtCbox = new System.Windows.Forms.CheckBox();
|
this.downloadCoverArtCbox = new System.Windows.Forms.CheckBox();
|
||||||
this.createCueSheetCbox = new System.Windows.Forms.CheckBox();
|
this.createCueSheetCbox = new System.Windows.Forms.CheckBox();
|
||||||
this.mergeOpeningEndCreditsCbox = new System.Windows.Forms.CheckBox();
|
this.audiobookFixupsGb = new System.Windows.Forms.GroupBox();
|
||||||
this.badBookGb.SuspendLayout();
|
this.badBookGb.SuspendLayout();
|
||||||
this.tabControl.SuspendLayout();
|
this.tabControl.SuspendLayout();
|
||||||
this.tab1ImportantSettings.SuspendLayout();
|
this.tab1ImportantSettings.SuspendLayout();
|
||||||
@ -125,6 +126,7 @@
|
|||||||
this.lameQualityGb.SuspendLayout();
|
this.lameQualityGb.SuspendLayout();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.lameVBRQualityTb)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.lameVBRQualityTb)).BeginInit();
|
||||||
this.groupBox2.SuspendLayout();
|
this.groupBox2.SuspendLayout();
|
||||||
|
this.audiobookFixupsGb.SuspendLayout();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
// booksLocationDescLbl
|
// booksLocationDescLbl
|
||||||
@ -252,7 +254,7 @@
|
|||||||
// stripAudibleBrandingCbox
|
// stripAudibleBrandingCbox
|
||||||
//
|
//
|
||||||
this.stripAudibleBrandingCbox.AutoSize = true;
|
this.stripAudibleBrandingCbox.AutoSize = true;
|
||||||
this.stripAudibleBrandingCbox.Location = new System.Drawing.Point(19, 193);
|
this.stripAudibleBrandingCbox.Location = new System.Drawing.Point(13, 72);
|
||||||
this.stripAudibleBrandingCbox.Name = "stripAudibleBrandingCbox";
|
this.stripAudibleBrandingCbox.Name = "stripAudibleBrandingCbox";
|
||||||
this.stripAudibleBrandingCbox.Size = new System.Drawing.Size(143, 34);
|
this.stripAudibleBrandingCbox.Size = new System.Drawing.Size(143, 34);
|
||||||
this.stripAudibleBrandingCbox.TabIndex = 13;
|
this.stripAudibleBrandingCbox.TabIndex = 13;
|
||||||
@ -262,7 +264,7 @@
|
|||||||
// splitFilesByChapterCbox
|
// splitFilesByChapterCbox
|
||||||
//
|
//
|
||||||
this.splitFilesByChapterCbox.AutoSize = true;
|
this.splitFilesByChapterCbox.AutoSize = true;
|
||||||
this.splitFilesByChapterCbox.Location = new System.Drawing.Point(19, 118);
|
this.splitFilesByChapterCbox.Location = new System.Drawing.Point(13, 22);
|
||||||
this.splitFilesByChapterCbox.Name = "splitFilesByChapterCbox";
|
this.splitFilesByChapterCbox.Name = "splitFilesByChapterCbox";
|
||||||
this.splitFilesByChapterCbox.Size = new System.Drawing.Size(162, 19);
|
this.splitFilesByChapterCbox.Size = new System.Drawing.Size(162, 19);
|
||||||
this.splitFilesByChapterCbox.TabIndex = 13;
|
this.splitFilesByChapterCbox.TabIndex = 13;
|
||||||
@ -275,7 +277,7 @@
|
|||||||
this.allowLibationFixupCbox.AutoSize = true;
|
this.allowLibationFixupCbox.AutoSize = true;
|
||||||
this.allowLibationFixupCbox.Checked = true;
|
this.allowLibationFixupCbox.Checked = true;
|
||||||
this.allowLibationFixupCbox.CheckState = System.Windows.Forms.CheckState.Checked;
|
this.allowLibationFixupCbox.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||||
this.allowLibationFixupCbox.Location = new System.Drawing.Point(19, 18);
|
this.allowLibationFixupCbox.Location = new System.Drawing.Point(19, 118);
|
||||||
this.allowLibationFixupCbox.Name = "allowLibationFixupCbox";
|
this.allowLibationFixupCbox.Name = "allowLibationFixupCbox";
|
||||||
this.allowLibationFixupCbox.Size = new System.Drawing.Size(163, 19);
|
this.allowLibationFixupCbox.Size = new System.Drawing.Size(163, 19);
|
||||||
this.allowLibationFixupCbox.TabIndex = 10;
|
this.allowLibationFixupCbox.TabIndex = 10;
|
||||||
@ -286,7 +288,7 @@
|
|||||||
// convertLossyRb
|
// convertLossyRb
|
||||||
//
|
//
|
||||||
this.convertLossyRb.AutoSize = true;
|
this.convertLossyRb.AutoSize = true;
|
||||||
this.convertLossyRb.Location = new System.Drawing.Point(19, 257);
|
this.convertLossyRb.Location = new System.Drawing.Point(13, 136);
|
||||||
this.convertLossyRb.Name = "convertLossyRb";
|
this.convertLossyRb.Name = "convertLossyRb";
|
||||||
this.convertLossyRb.Size = new System.Drawing.Size(329, 19);
|
this.convertLossyRb.Size = new System.Drawing.Size(329, 19);
|
||||||
this.convertLossyRb.TabIndex = 12;
|
this.convertLossyRb.TabIndex = 12;
|
||||||
@ -298,7 +300,7 @@
|
|||||||
//
|
//
|
||||||
this.convertLosslessRb.AutoSize = true;
|
this.convertLosslessRb.AutoSize = true;
|
||||||
this.convertLosslessRb.Checked = true;
|
this.convertLosslessRb.Checked = true;
|
||||||
this.convertLosslessRb.Location = new System.Drawing.Point(19, 232);
|
this.convertLosslessRb.Location = new System.Drawing.Point(13, 111);
|
||||||
this.convertLosslessRb.Name = "convertLosslessRb";
|
this.convertLosslessRb.Name = "convertLosslessRb";
|
||||||
this.convertLosslessRb.Size = new System.Drawing.Size(335, 19);
|
this.convertLosslessRb.Size = new System.Drawing.Size(335, 19);
|
||||||
this.convertLosslessRb.TabIndex = 11;
|
this.convertLosslessRb.TabIndex = 11;
|
||||||
@ -603,14 +605,10 @@
|
|||||||
//
|
//
|
||||||
// tab4AudioFileOptions
|
// tab4AudioFileOptions
|
||||||
//
|
//
|
||||||
|
this.tab4AudioFileOptions.Controls.Add(this.audiobookFixupsGb);
|
||||||
this.tab4AudioFileOptions.Controls.Add(this.chapterTitleTemplateGb);
|
this.tab4AudioFileOptions.Controls.Add(this.chapterTitleTemplateGb);
|
||||||
this.tab4AudioFileOptions.Controls.Add(this.lameOptionsGb);
|
this.tab4AudioFileOptions.Controls.Add(this.lameOptionsGb);
|
||||||
this.tab4AudioFileOptions.Controls.Add(this.convertLossyRb);
|
|
||||||
this.tab4AudioFileOptions.Controls.Add(this.stripAudibleBrandingCbox);
|
|
||||||
this.tab4AudioFileOptions.Controls.Add(this.convertLosslessRb);
|
|
||||||
this.tab4AudioFileOptions.Controls.Add(this.stripUnabridgedCbox);
|
|
||||||
this.tab4AudioFileOptions.Controls.Add(this.mergeOpeningEndCreditsCbox);
|
this.tab4AudioFileOptions.Controls.Add(this.mergeOpeningEndCreditsCbox);
|
||||||
this.tab4AudioFileOptions.Controls.Add(this.splitFilesByChapterCbox);
|
|
||||||
this.tab4AudioFileOptions.Controls.Add(this.retainAaxFileCbox);
|
this.tab4AudioFileOptions.Controls.Add(this.retainAaxFileCbox);
|
||||||
this.tab4AudioFileOptions.Controls.Add(this.downloadCoverArtCbox);
|
this.tab4AudioFileOptions.Controls.Add(this.downloadCoverArtCbox);
|
||||||
this.tab4AudioFileOptions.Controls.Add(this.createCueSheetCbox);
|
this.tab4AudioFileOptions.Controls.Add(this.createCueSheetCbox);
|
||||||
@ -982,17 +980,27 @@
|
|||||||
// stripUnabridgedCbox
|
// stripUnabridgedCbox
|
||||||
//
|
//
|
||||||
this.stripUnabridgedCbox.AutoSize = true;
|
this.stripUnabridgedCbox.AutoSize = true;
|
||||||
this.stripUnabridgedCbox.Location = new System.Drawing.Point(19, 168);
|
this.stripUnabridgedCbox.Location = new System.Drawing.Point(13, 47);
|
||||||
this.stripUnabridgedCbox.Name = "stripUnabridgedCbox";
|
this.stripUnabridgedCbox.Name = "stripUnabridgedCbox";
|
||||||
this.stripUnabridgedCbox.Size = new System.Drawing.Size(147, 19);
|
this.stripUnabridgedCbox.Size = new System.Drawing.Size(147, 19);
|
||||||
this.stripUnabridgedCbox.TabIndex = 13;
|
this.stripUnabridgedCbox.TabIndex = 13;
|
||||||
this.stripUnabridgedCbox.Text = "[StripUnabridged desc]";
|
this.stripUnabridgedCbox.Text = "[StripUnabridged desc]";
|
||||||
this.stripUnabridgedCbox.UseVisualStyleBackColor = true;
|
this.stripUnabridgedCbox.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
|
// mergeOpeningEndCreditsCbox
|
||||||
|
//
|
||||||
|
this.mergeOpeningEndCreditsCbox.AutoSize = true;
|
||||||
|
this.mergeOpeningEndCreditsCbox.Location = new System.Drawing.Point(19, 93);
|
||||||
|
this.mergeOpeningEndCreditsCbox.Name = "mergeOpeningEndCreditsCbox";
|
||||||
|
this.mergeOpeningEndCreditsCbox.Size = new System.Drawing.Size(198, 19);
|
||||||
|
this.mergeOpeningEndCreditsCbox.TabIndex = 13;
|
||||||
|
this.mergeOpeningEndCreditsCbox.Text = "[MergeOpeningEndCredits desc]";
|
||||||
|
this.mergeOpeningEndCreditsCbox.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
// retainAaxFileCbox
|
// retainAaxFileCbox
|
||||||
//
|
//
|
||||||
this.retainAaxFileCbox.AutoSize = true;
|
this.retainAaxFileCbox.AutoSize = true;
|
||||||
this.retainAaxFileCbox.Location = new System.Drawing.Point(19, 93);
|
this.retainAaxFileCbox.Location = new System.Drawing.Point(19, 68);
|
||||||
this.retainAaxFileCbox.Name = "retainAaxFileCbox";
|
this.retainAaxFileCbox.Name = "retainAaxFileCbox";
|
||||||
this.retainAaxFileCbox.Size = new System.Drawing.Size(132, 19);
|
this.retainAaxFileCbox.Size = new System.Drawing.Size(132, 19);
|
||||||
this.retainAaxFileCbox.TabIndex = 10;
|
this.retainAaxFileCbox.TabIndex = 10;
|
||||||
@ -1005,7 +1013,7 @@
|
|||||||
this.downloadCoverArtCbox.AutoSize = true;
|
this.downloadCoverArtCbox.AutoSize = true;
|
||||||
this.downloadCoverArtCbox.Checked = true;
|
this.downloadCoverArtCbox.Checked = true;
|
||||||
this.downloadCoverArtCbox.CheckState = System.Windows.Forms.CheckState.Checked;
|
this.downloadCoverArtCbox.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||||
this.downloadCoverArtCbox.Location = new System.Drawing.Point(19, 68);
|
this.downloadCoverArtCbox.Location = new System.Drawing.Point(19, 43);
|
||||||
this.downloadCoverArtCbox.Name = "downloadCoverArtCbox";
|
this.downloadCoverArtCbox.Name = "downloadCoverArtCbox";
|
||||||
this.downloadCoverArtCbox.Size = new System.Drawing.Size(162, 19);
|
this.downloadCoverArtCbox.Size = new System.Drawing.Size(162, 19);
|
||||||
this.downloadCoverArtCbox.TabIndex = 10;
|
this.downloadCoverArtCbox.TabIndex = 10;
|
||||||
@ -1018,7 +1026,7 @@
|
|||||||
this.createCueSheetCbox.AutoSize = true;
|
this.createCueSheetCbox.AutoSize = true;
|
||||||
this.createCueSheetCbox.Checked = true;
|
this.createCueSheetCbox.Checked = true;
|
||||||
this.createCueSheetCbox.CheckState = System.Windows.Forms.CheckState.Checked;
|
this.createCueSheetCbox.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||||
this.createCueSheetCbox.Location = new System.Drawing.Point(19, 43);
|
this.createCueSheetCbox.Location = new System.Drawing.Point(19, 18);
|
||||||
this.createCueSheetCbox.Name = "createCueSheetCbox";
|
this.createCueSheetCbox.Name = "createCueSheetCbox";
|
||||||
this.createCueSheetCbox.Size = new System.Drawing.Size(145, 19);
|
this.createCueSheetCbox.Size = new System.Drawing.Size(145, 19);
|
||||||
this.createCueSheetCbox.TabIndex = 10;
|
this.createCueSheetCbox.TabIndex = 10;
|
||||||
@ -1026,16 +1034,19 @@
|
|||||||
this.createCueSheetCbox.UseVisualStyleBackColor = true;
|
this.createCueSheetCbox.UseVisualStyleBackColor = true;
|
||||||
this.createCueSheetCbox.CheckedChanged += new System.EventHandler(this.allowLibationFixupCbox_CheckedChanged);
|
this.createCueSheetCbox.CheckedChanged += new System.EventHandler(this.allowLibationFixupCbox_CheckedChanged);
|
||||||
//
|
//
|
||||||
// mergeBeginningEndCreditsCbox
|
// audiobookFixupsGb
|
||||||
//
|
//
|
||||||
this.mergeOpeningEndCreditsCbox.AutoSize = true;
|
this.audiobookFixupsGb.Controls.Add(this.splitFilesByChapterCbox);
|
||||||
this.mergeOpeningEndCreditsCbox.Location = new System.Drawing.Point(19, 143);
|
this.audiobookFixupsGb.Controls.Add(this.stripUnabridgedCbox);
|
||||||
this.mergeOpeningEndCreditsCbox.Name = "mergeOpeningEndCreditsCbox";
|
this.audiobookFixupsGb.Controls.Add(this.convertLosslessRb);
|
||||||
this.mergeOpeningEndCreditsCbox.Size = new System.Drawing.Size(206, 19);
|
this.audiobookFixupsGb.Controls.Add(this.convertLossyRb);
|
||||||
this.mergeOpeningEndCreditsCbox.TabIndex = 13;
|
this.audiobookFixupsGb.Controls.Add(this.stripAudibleBrandingCbox);
|
||||||
this.mergeOpeningEndCreditsCbox.Text = "[MergeOpeningEndCredits desc]";
|
this.audiobookFixupsGb.Location = new System.Drawing.Point(6, 143);
|
||||||
this.mergeOpeningEndCreditsCbox.UseVisualStyleBackColor = true;
|
this.audiobookFixupsGb.Name = "audiobookFixupsGb";
|
||||||
this.mergeOpeningEndCreditsCbox.CheckedChanged += new System.EventHandler(this.splitFilesByChapterCbox_CheckedChanged);
|
this.audiobookFixupsGb.Size = new System.Drawing.Size(403, 160);
|
||||||
|
this.audiobookFixupsGb.TabIndex = 19;
|
||||||
|
this.audiobookFixupsGb.TabStop = false;
|
||||||
|
this.audiobookFixupsGb.Text = "Audiobook Fix-ups";
|
||||||
//
|
//
|
||||||
// SettingsDialog
|
// SettingsDialog
|
||||||
//
|
//
|
||||||
@ -1083,6 +1094,8 @@
|
|||||||
((System.ComponentModel.ISupportInitialize)(this.lameVBRQualityTb)).EndInit();
|
((System.ComponentModel.ISupportInitialize)(this.lameVBRQualityTb)).EndInit();
|
||||||
this.groupBox2.ResumeLayout(false);
|
this.groupBox2.ResumeLayout(false);
|
||||||
this.groupBox2.PerformLayout();
|
this.groupBox2.PerformLayout();
|
||||||
|
this.audiobookFixupsGb.ResumeLayout(false);
|
||||||
|
this.audiobookFixupsGb.PerformLayout();
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1169,5 +1182,6 @@
|
|||||||
private System.Windows.Forms.TextBox chapterTitleTemplateTb;
|
private System.Windows.Forms.TextBox chapterTitleTemplateTb;
|
||||||
private System.Windows.Forms.Button editCharreplacementBtn;
|
private System.Windows.Forms.Button editCharreplacementBtn;
|
||||||
private System.Windows.Forms.CheckBox mergeOpeningEndCreditsCbox;
|
private System.Windows.Forms.CheckBox mergeOpeningEndCreditsCbox;
|
||||||
|
private System.Windows.Forms.GroupBox audiobookFixupsGb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -148,6 +148,141 @@ namespace FileLiberator.Tests
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
private static Chapter[] HierarchicalChapters_LongerParents => new Chapter[]
|
||||||
|
{
|
||||||
|
new ()
|
||||||
|
{
|
||||||
|
Title = "Opening Credits",
|
||||||
|
StartOffsetMs = 0,
|
||||||
|
StartOffsetSec = 0,
|
||||||
|
LengthMs = 10000,
|
||||||
|
},
|
||||||
|
new ()
|
||||||
|
{
|
||||||
|
Title = "Book 1",
|
||||||
|
StartOffsetMs = 10000,
|
||||||
|
StartOffsetSec = 10,
|
||||||
|
LengthMs = 15000,
|
||||||
|
Chapters = new Chapter[]
|
||||||
|
{
|
||||||
|
new ()
|
||||||
|
{
|
||||||
|
Title = "Part 1",
|
||||||
|
StartOffsetMs = 25000,
|
||||||
|
StartOffsetSec = 25,
|
||||||
|
LengthMs = 2000,
|
||||||
|
Chapters = new Chapter[]
|
||||||
|
{
|
||||||
|
new ()
|
||||||
|
{
|
||||||
|
Title = "Chapter 1",
|
||||||
|
StartOffsetMs = 27000,
|
||||||
|
StartOffsetSec = 27,
|
||||||
|
LengthMs = 73000,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "Chapter 2",
|
||||||
|
StartOffsetMs = 100000,
|
||||||
|
StartOffsetSec = 100,
|
||||||
|
LengthMs = 100000,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "Part 2",
|
||||||
|
StartOffsetMs = 200000,
|
||||||
|
StartOffsetSec = 200,
|
||||||
|
LengthMs = 2000,
|
||||||
|
Chapters = new Chapter[]
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "Chapter 3",
|
||||||
|
StartOffsetMs = 202000,
|
||||||
|
StartOffsetSec = 202,
|
||||||
|
LengthMs = 98000,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "Chapter 4",
|
||||||
|
StartOffsetMs = 300000,
|
||||||
|
StartOffsetSec = 300,
|
||||||
|
LengthMs = 100000,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "Book 2",
|
||||||
|
StartOffsetMs = 400000,
|
||||||
|
StartOffsetSec = 400,
|
||||||
|
LengthMs = 2000,
|
||||||
|
Chapters = new Chapter[]
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "Part 3",
|
||||||
|
StartOffsetMs = 402000,
|
||||||
|
StartOffsetSec = 402,
|
||||||
|
LengthMs = 20000,
|
||||||
|
Chapters = new Chapter[]
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "Chapter 5",
|
||||||
|
StartOffsetMs = 422000,
|
||||||
|
StartOffsetSec = 422,
|
||||||
|
LengthMs = 78000,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "Chapter 6",
|
||||||
|
StartOffsetMs = 500000,
|
||||||
|
StartOffsetSec = 500,
|
||||||
|
LengthMs = 100000,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "Part 4",
|
||||||
|
StartOffsetMs = 600000,
|
||||||
|
StartOffsetSec = 600,
|
||||||
|
LengthMs = 2000,
|
||||||
|
Chapters = new Chapter[]
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "Chapter 7",
|
||||||
|
StartOffsetMs = 602000,
|
||||||
|
StartOffsetSec = 602,
|
||||||
|
LengthMs = 98000,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "Chapter 8",
|
||||||
|
StartOffsetMs = 700000,
|
||||||
|
StartOffsetSec = 700,
|
||||||
|
LengthMs = 100000,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "End Credits",
|
||||||
|
StartOffsetMs = 800000,
|
||||||
|
StartOffsetSec = 800,
|
||||||
|
LengthMs = 10000,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void Chapters_CombineCredits()
|
public void Chapters_CombineCredits()
|
||||||
{
|
{
|
||||||
@ -299,6 +434,102 @@ namespace FileLiberator.Tests
|
|||||||
checkChapters(flatChapters, expected);
|
checkChapters(flatChapters, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void HierarchicalChapters_LongerParents_Flatten()
|
||||||
|
{
|
||||||
|
var expected = new Chapter[]
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "Opening Credits",
|
||||||
|
StartOffsetMs = 0,
|
||||||
|
StartOffsetSec = 0,
|
||||||
|
LengthMs = 10000,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "Book 1",
|
||||||
|
StartOffsetMs = 10000,
|
||||||
|
StartOffsetSec = 10,
|
||||||
|
LengthMs = 15000,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "Book 1: Part 1: Chapter 1",
|
||||||
|
StartOffsetMs = 25000,
|
||||||
|
StartOffsetSec = 25,
|
||||||
|
LengthMs = 75000,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "Book 1: Part 1: Chapter 2",
|
||||||
|
StartOffsetMs = 100000,
|
||||||
|
StartOffsetSec = 100,
|
||||||
|
LengthMs = 100000,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "Book 1: Part 2: Chapter 3",
|
||||||
|
StartOffsetMs = 200000,
|
||||||
|
StartOffsetSec = 200,
|
||||||
|
LengthMs = 100000,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "Book 1: Part 2: Chapter 4",
|
||||||
|
StartOffsetMs = 300000,
|
||||||
|
StartOffsetSec = 300,
|
||||||
|
LengthMs = 100000,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "Book 2: Part 3",
|
||||||
|
StartOffsetMs = 400000,
|
||||||
|
StartOffsetSec = 400,
|
||||||
|
LengthMs = 22000,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "Book 2: Part 3: Chapter 5",
|
||||||
|
StartOffsetMs = 422000,
|
||||||
|
StartOffsetSec = 422,
|
||||||
|
LengthMs = 78000,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "Book 2: Part 3: Chapter 6",
|
||||||
|
StartOffsetMs = 500000,
|
||||||
|
StartOffsetSec = 500,
|
||||||
|
LengthMs = 100000,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "Book 2: Part 4: Chapter 7",
|
||||||
|
StartOffsetMs = 600000,
|
||||||
|
StartOffsetSec = 600,
|
||||||
|
LengthMs = 100000,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "Book 2: Part 4: Chapter 8",
|
||||||
|
StartOffsetMs = 700000,
|
||||||
|
StartOffsetSec = 700,
|
||||||
|
LengthMs = 100000,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Title = "End Credits",
|
||||||
|
StartOffsetMs = 800000,
|
||||||
|
StartOffsetSec = 800,
|
||||||
|
LengthMs = 10000,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var flatChapters = DownloadDecryptBook.flattenChapters(HierarchicalChapters_LongerParents);
|
||||||
|
|
||||||
|
checkChapters(flatChapters, expected);
|
||||||
|
}
|
||||||
|
|
||||||
private static void checkChapters(IList<Chapter> value, IList<Chapter> expected)
|
private static void checkChapters(IList<Chapter> value, IList<Chapter> expected)
|
||||||
{
|
{
|
||||||
value.Count.Should().Be(expected.Count);
|
value.Count.Should().Be(expected.Count);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user