From 2f4a0bdc9fa0630c02bf7b3504de5f7162f10c19 Mon Sep 17 00:00:00 2001 From: John Andrews Date: Fri, 26 Apr 2024 11:43:14 +1200 Subject: [PATCH] FF-1438: Create Audio Book now copies metadata from first file into final combined file --- AudioNodes/AudioBooks/CreateAudioBook.cs | 17 ++- AudioNodes/Tests/AudioTestBase.cs | 42 +++++++ AudioNodes/Tests/ConvertTests.cs | 15 +-- AudioNodes/Tests/CreateAudioBookTests.cs | 147 +++++++++++------------ AudioNodes/Tests/EmbedArtworkTests.cs | 35 +----- 5 files changed, 134 insertions(+), 122 deletions(-) create mode 100644 AudioNodes/Tests/AudioTestBase.cs diff --git a/AudioNodes/AudioBooks/CreateAudioBook.cs b/AudioNodes/AudioBooks/CreateAudioBook.cs index be4f2537..001ddd02 100644 --- a/AudioNodes/AudioBooks/CreateAudioBook.cs +++ b/AudioNodes/AudioBooks/CreateAudioBook.cs @@ -1,3 +1,5 @@ +using FileFlows.AudioNodes.Helpers; + namespace FileFlows.AudioNodes; /// @@ -73,7 +75,7 @@ public class CreateAudioBook: AudioNode var dir = args.IsDirectory ? args.WorkingFile : FileHelper.GetDirectory(args.WorkingFile); - var allowedExtensions = new List { ".mp3", ".aac", ".m4b", ".m4a" }; + var allowedExtensions = new List { ".mp3", ".aac", ".m4b", ".m4a", ".flac" }; var dirFiles = args.FileService.GetFiles(dir, "*.*"); List files = new (); foreach (var file in dirFiles.ValueOrDefault ?? new string[] {}) @@ -122,6 +124,9 @@ public class CreateAudioBook: AudioNode args.Logger.ILog($"Number [{number}] found in: " + shortname); return number; }).ToList(); + + var readResult = new AudioInfoHelper(ffmpeg, ffprobe, args.Logger).Read(files.First()); + var audioInfo = readResult.IsFailed ? null : readResult.Value; string metadataFile = FileHelper.Combine(args.TempPath, "CreateAudioBookChapters-metadata.txt"); TimeSpan current = TimeSpan.Zero; @@ -166,6 +171,16 @@ public class CreateAudioBook: AudioNode metadataFile }; + if (audioInfo != null) + { + audioInfo.Track = 0; + audioInfo.TotalDiscs = 0; + audioInfo.TotalTracks = 0; + var metadata = MetadataHelper.GetMetadataParameters(audioInfo); + if (metadata.Any()) + execArgs.AddRange(metadata); + } + if (string.IsNullOrEmpty(artwork) == false) { execArgs.AddRange(new [] diff --git a/AudioNodes/Tests/AudioTestBase.cs b/AudioNodes/Tests/AudioTestBase.cs new file mode 100644 index 00000000..4a1fc745 --- /dev/null +++ b/AudioNodes/Tests/AudioTestBase.cs @@ -0,0 +1,42 @@ +#if(DEBUG) + +using FileFlows.AudioNodes.Tests; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace AudioNodes.Tests; + +public abstract class AudioTestBase +{ + private TestContext testContextInstance; + + internal TestLogger logger = new (); + + public TestContext TestContext + { + get { return testContextInstance; } + set { testContextInstance = value; } + } + + protected readonly string ffmpeg = (OperatingSystem.IsLinux() ? "/usr/local/bin/ffmpeg" : @"C:\utils\ffmpeg\ffmpeg.exe"); + protected readonly string ffprobe = (OperatingSystem.IsLinux() ? "/usr/local/bin/ffprobe" : @"C:\utils\ffmpeg\ffprobe.exe"); + + + protected NodeParameters GetNodeParameters(string file, bool isDirectory = false) + { + var args = new FileFlows.Plugin.NodeParameters(file, logger, isDirectory, string.Empty, new LocalFileService()); + + args.GetToolPathActual = (string tool) => + { + if (tool.ToLowerInvariant() == "ffmpeg") + return ffmpeg; + if (tool.ToLowerInvariant() == "ffprobe") + return ffprobe; + return null; + }; + args.TempPath = @"/home/john/Music/temp"; + + return args; + } +} + +#endif \ No newline at end of file diff --git a/AudioNodes/Tests/ConvertTests.cs b/AudioNodes/Tests/ConvertTests.cs index 5094083d..b4afe8a5 100644 --- a/AudioNodes/Tests/ConvertTests.cs +++ b/AudioNodes/Tests/ConvertTests.cs @@ -7,16 +7,8 @@ using AudioNodes.Tests; namespace FileFlows.AudioNodes.Tests; [TestClass] -public class ConvertTests +public class ConvertTests : AudioTestBase { - private TestContext testContextInstance; - - public TestContext TestContext - { - get { return testContextInstance; } - set { testContextInstance = value; } - } - [TestMethod] public void Convert_FlacToAac() { @@ -217,9 +209,8 @@ public class ConvertTests const string file = @"D:\videos\testfiles\basic.mkv"; ConvertToAAC node = new(); - var logger = new TestLogger(); - var args = new FileFlows.Plugin.NodeParameters(file, logger, false, string.Empty, null); - args.GetToolPathActual = (string tool) => @"C:\utils\ffmpeg\ffmpeg.exe"; + var args = GetNodeParameters(file); + args.TempPath = @"D:\music\temp"; new AudioFile().Execute(args); // need to read the Audio info and set it node.Normalize = true; diff --git a/AudioNodes/Tests/CreateAudioBookTests.cs b/AudioNodes/Tests/CreateAudioBookTests.cs index 4203c03e..0121d090 100644 --- a/AudioNodes/Tests/CreateAudioBookTests.cs +++ b/AudioNodes/Tests/CreateAudioBookTests.cs @@ -1,76 +1,71 @@ -// #if(DEBUG) -// -// using System.Reflection.Metadata; -// using Microsoft.VisualStudio.TestTools.UnitTesting; -// using FileFlows.AudioNodes.AudioBooks; -// -// namespace FileFlows.AudioNodes.Tests; -// -// -// [TestClass] -// public class CreateAudioBookTests -// { -// -// [TestMethod] -// public void CreateAudioBookTest_01() -// { -// const string folder = "/home/john/Music/Audio Books/James Dashner (2020) Maze Runner 05.5"; -// RunTest(folder); -// } -// -// [TestMethod] -// public void CreateAudioBookTest_02() -// { -// const string folder = @"/home/john/Music/Audio Books/Charlie and the Great Glass Elevator"; -// RunTest(folder); -// } -// -// [TestMethod] -// public void CreateAudioBookTest_03() -// { -// const string folder = @"/home/john/Music/Audio Books/Scott Westerfeld - Afterworlds"; -// RunTest(folder); -// } -// -// [TestMethod] -// public void CreateAudioBookTest_04() -// { -// const string folder = @"/home/john/Music/Audio Books/Small Town-Lawrence Block"; -// RunTest(folder); -// } -// -// [TestMethod] -// public void CreateAudioBookTest_05() -// { -// const string folder = @"/home/john/Music/Audio Books/Shatter City"; -// RunTest(folder, 2); -// } -// -// [TestMethod] -// public void CreateAudioBookTest_06() -// { -// const string folder = @"/home/john/Music/Audio Books/Among the Betrayed - Margaret Peterson Haddix (M4B)"; -// RunTest(folder, 2); -// } -// -// private void RunTest(string folder, int expected = 1) -// { -// CreateAudioBook node = new (); -// var logger = new TestLogger(); -// var args = new FileFlows.Plugin.NodeParameters(folder,logger, true, string.Empty); -// args.GetToolPathActual = (string tool) => @"/usr/bin/ffmpeg"; -// const string tempPath= @"/home/john/Music/test"; -// args.TempPath =tempPath ; -// foreach (var file in new DirectoryInfo(tempPath).GetFiles( "*.*")) -// { -// file.Delete(); -// } -// -// int output = node.Execute(args); -// -// var log = logger.ToString(); -// Assert.AreEqual(expected, output); -// -// } -// } -// #endif \ No newline at end of file +#if(DEBUG) + +using AudioNodes.Tests; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace FileFlows.AudioNodes.Tests; + + +[TestClass] +public class CreateAudioBookTests : AudioTestBase +{ + [TestMethod] + public void CreateAudioBookTest_01() + { + const string folder = "/home/john/Music/unprocessed/Aqua/Aquarius (2000)"; + RunTest(folder); + } + + [TestMethod] + public void CreateAudioBookTest_02() + { + const string folder = @"/home/john/Music/Audio Books/Charlie and the Great Glass Elevator"; + RunTest(folder); + } + + [TestMethod] + public void CreateAudioBookTest_03() + { + const string folder = @"/home/john/Music/Audio Books/Scott Westerfeld - Afterworlds"; + RunTest(folder); + } + + [TestMethod] + public void CreateAudioBookTest_04() + { + const string folder = @"/home/john/Music/Audio Books/Small Town-Lawrence Block"; + RunTest(folder); + } + + [TestMethod] + public void CreateAudioBookTest_05() + { + const string folder = @"/home/john/Music/Audio Books/Shatter City"; + RunTest(folder, 2); + } + + [TestMethod] + public void CreateAudioBookTest_06() + { + const string folder = @"/home/john/Music/Audio Books/Among the Betrayed - Margaret Peterson Haddix (M4B)"; + RunTest(folder, 2); + } + + private void RunTest(string folder, int expected = 1) + { + CreateAudioBook node = new (); + var args = GetNodeParameters(folder, isDirectory: true); + foreach (var file in new System.IO.DirectoryInfo(args.TempPath).GetFiles( "*.*")) + { + file.Delete(); + } + + int output = node.Execute(args); + + var log = logger.ToString(); + TestContext.WriteLine(log); + Assert.AreEqual(expected, output); + + } +} +#endif \ No newline at end of file diff --git a/AudioNodes/Tests/EmbedArtworkTests.cs b/AudioNodes/Tests/EmbedArtworkTests.cs index 113f2662..9eef57a1 100644 --- a/AudioNodes/Tests/EmbedArtworkTests.cs +++ b/AudioNodes/Tests/EmbedArtworkTests.cs @@ -7,26 +7,9 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; namespace AudioNodes.Tests; [TestClass] -public class EmbedArtworkTests +public class EmbedArtworkTests : AudioTestBase { - /// - /// The test context instance - /// - private TestContext testContextInstance; - /// - /// Gets or sets the test context - /// - public TestContext TestContext - { - get { return testContextInstance; } - set { testContextInstance = value; } - } - - readonly string ffmpeg = (OperatingSystem.IsLinux() ? "/usr/local/bin/ffmpeg" : @"C:\utils\ffmpeg\ffmpeg.exe"); - readonly string ffprobe = (OperatingSystem.IsLinux() ? "/usr/local/bin/ffprobe" : @"C:\utils\ffmpeg\ffprobe.exe"); - - [TestMethod] public void SingleArtwork() { @@ -82,24 +65,10 @@ public class EmbedArtworkTests void ConvertAudio(Node convertNode) { - var logger = new TestLogger(); //const string file = "/home/john/Music/unprocessed/Aqua/Aquarium (1997)/zombie.mp3"; const string file = "/home/john/Music/unprocessed/Aqua/Aquarius (2000)/Aqua - Aquarius - 01 - Cartoon Heroes.flac"; - var args = new NodeParameters(file, logger, false, string.Empty, new LocalFileService()) - { - LibraryFileName = file - }; - - args.GetToolPathActual = (string tool) => - { - if (tool.ToLowerInvariant() == "ffmpeg") - return ffmpeg; - if (tool.ToLowerInvariant() == "ffprobe") - return ffprobe; - return null; - }; - args.TempPath = @"/home/john/Music/temp"; + var args = GetNodeParameters(file); var audioFile = new AudioFile(); audioFile.PreExecute(args);