From 98c194b462789dfef76553f2760c688c7ce2e3e1 Mon Sep 17 00:00:00 2001 From: John Andrews Date: Sat, 6 Jul 2024 10:19:14 +1200 Subject: [PATCH] FF-1667: ConvertAudio AAC High Efficiency not used on fixed bitrate --- .../Nodes/ConvertFlowElements/ConvertNode.cs | 5 + AudioNodes/Tests/AudioTestBase.cs | 2 +- AudioNodes/Tests/ConvertTests.cs | 17 +++ AudioNodes/Tests/EmbedArtworkTests.cs | 1 - AudioNodes/Tests/TestLogger.cs | 144 +++++++++++------- AudioNodes/Tests/_LocalFileService.cs | 2 +- AudioNodes/Tests/_TestBase.cs | 1 + FileFlows.Plugin.dll | Bin 146944 -> 146944 bytes FileFlows.Plugin.pdb | Bin 36360 -> 36364 bytes 9 files changed, 111 insertions(+), 61 deletions(-) diff --git a/AudioNodes/Nodes/ConvertFlowElements/ConvertNode.cs b/AudioNodes/Nodes/ConvertFlowElements/ConvertNode.cs index 852edc83..9b7da153 100644 --- a/AudioNodes/Nodes/ConvertFlowElements/ConvertNode.cs +++ b/AudioNodes/Nodes/ConvertFlowElements/ConvertNode.cs @@ -109,6 +109,11 @@ namespace FileFlows.AudioNodes "-ab", (bitrate == -1 ? GetSourceBitrate(args).ToString() : bitrate + "k") }); + if (Codec == "aac" && HighEfficiency) + { + extension = "m4a"; + ffArgs.AddRange(new[] { "-profile:a", "aac_he_v2" }); + } } if (SampleRate > 0) diff --git a/AudioNodes/Tests/AudioTestBase.cs b/AudioNodes/Tests/AudioTestBase.cs index a33569ed..8006e179 100644 --- a/AudioNodes/Tests/AudioTestBase.cs +++ b/AudioNodes/Tests/AudioTestBase.cs @@ -9,7 +9,7 @@ public abstract class AudioTestBase : TestBase { protected NodeParameters GetNodeParameters(string file, bool isDirectory = false) { - var args = new FileFlows.Plugin.NodeParameters(file, Logger, isDirectory, string.Empty, new LocalFileService()); + var args = new NodeParameters(file, Logger, isDirectory, string.Empty, new LocalFileService()); args.GetToolPathActual = (string tool) => { diff --git a/AudioNodes/Tests/ConvertTests.cs b/AudioNodes/Tests/ConvertTests.cs index 5401ef60..650cd0e9 100644 --- a/AudioNodes/Tests/ConvertTests.cs +++ b/AudioNodes/Tests/ConvertTests.cs @@ -112,6 +112,23 @@ public class ConvertTests : AudioTestBase } + [TestMethod] + public void Convert_AacHighEfficient() + { + var args = GetNodeParameters(TestFile_Mp3); + var af = new AudioFile(); + af.PreExecute(args); + af.Execute(args); // need to read the Audio info and set it + + ConvertToAAC ele = new(); + ele.HighEfficiency = true; + ele.Bitrate = 192; + ele.PreExecute(args); + int output = ele.Execute(args); + + Assert.AreEqual(1, output); + } + [TestMethod] public void Convert_Mp3ToMp3_Bitrate() { diff --git a/AudioNodes/Tests/EmbedArtworkTests.cs b/AudioNodes/Tests/EmbedArtworkTests.cs index 9520c6a6..d4b205b5 100644 --- a/AudioNodes/Tests/EmbedArtworkTests.cs +++ b/AudioNodes/Tests/EmbedArtworkTests.cs @@ -78,7 +78,6 @@ public class EmbedArtworkTests : AudioTestBase var result = convertNode.Execute(args); var log = Logger.ToString(); Assert.AreEqual(1, result); - Logger.Clear(); var ele = new EmbedArtwork(); var output = ele.Execute(args); diff --git a/AudioNodes/Tests/TestLogger.cs b/AudioNodes/Tests/TestLogger.cs index 919a0ca9..5be157f0 100644 --- a/AudioNodes/Tests/TestLogger.cs +++ b/AudioNodes/Tests/TestLogger.cs @@ -1,67 +1,95 @@ #if(DEBUG) -namespace FileFlows.AudioNodes.Tests +using FileFlows.Plugin; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FileFlows.AudioNodes.Tests; + +/// +/// A logger for tests that stores the logs in memory +/// +public class TestLogger : ILogger { - using FileFlows.Plugin; - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - using System.Threading.Tasks; + private readonly List Messages = new(); - internal class TestLogger : ILogger + /// + /// Writes an information log message + /// + /// the log parameters + public void ILog(params object[] args) + => Log(LogType.Info, args); + + /// + /// Writes an debug log message + /// + /// the log parameters + public void DLog(params object[] args) + => Log(LogType.Debug, args); + + /// + /// Writes an warning log message + /// + /// the log parameters + public void WLog(params object[] args) + => Log(LogType.Warning, args); + + /// + /// Writes an error log message + /// + /// the log parameters + public void ELog(params object[] args) + => Log(LogType.Error, args); + + /// + /// Gets the tail of the log + /// + /// the number of messages to get + public string GetTail(int length = 50) { - private List Messages = new List(); - - public void DLog(params object[] args) => Log("DBUG", args); - - public void ELog(params object[] args) => Log("ERRR", args); - - public void ILog(params object[] args) => Log("INFO", args); - - public void WLog(params object[] args) => Log("WARN", args); - - private void Log(string type, object[] args) - { - if (args == null || args.Length == 0) - return; - string message = type + " -> " + - string.Join(", ", args.Select(x => - x == null ? "null" : - x.GetType().IsPrimitive || x is string ? x.ToString() : - System.Text.Json.JsonSerializer.Serialize(x))); - Messages.Add(message); - } - - public bool Contains(string message) - { - if (string.IsNullOrWhiteSpace(message)) - return false; - - string log = string.Join(Environment.NewLine, Messages); - return log.Contains(message); - } - - public override string ToString() - { - return String.Join(Environment.NewLine, this.Messages.ToArray()); - } - - public string GetTail(int length = 50) - { - if (length <= 0) - length = 50; - if (Messages.Count <= length) - return string.Join(Environment.NewLine, Messages); - return string.Join(Environment.NewLine, Messages.TakeLast(length)); - } - - /// - /// Clears the log - /// - public void Clear() - => Messages.Clear(); + if (Messages.Count <= length) + return string.Join(Environment.NewLine, Messages); + return string.Join(Environment.NewLine, Messages.TakeLast(50)); } + + /// + /// Logs a message + /// + /// the type of log to record + /// the arguments of the message + private void Log(LogType type, params object[] args) + { + string message = type + " -> " + string.Join(", ", args.Select(x => + x == null ? "null" : + x.GetType().IsPrimitive ? x.ToString() : + x is string ? x.ToString() : + System.Text.Json.JsonSerializer.Serialize(x))); + Writer?.Invoke(message); + Messages.Add(message); + } + + /// + /// Gets or sets an optional writer + /// + public Action Writer { get; set; } + + /// + /// Returns the entire log as a string + /// + /// the entire log + public override string ToString() + => string.Join(Environment.NewLine, Messages); + + /// + /// Checks if the log contains the text + /// + /// the text to check for + /// true if it contains it, otherwise false + public bool Contains(string text) + => Messages.Any(x => x.Contains(text)); } #endif \ No newline at end of file diff --git a/AudioNodes/Tests/_LocalFileService.cs b/AudioNodes/Tests/_LocalFileService.cs index 43a20d62..e09fee2c 100644 --- a/AudioNodes/Tests/_LocalFileService.cs +++ b/AudioNodes/Tests/_LocalFileService.cs @@ -367,7 +367,7 @@ public class LocalFileService : IFileService public Result DirectorySize(string path) { - throw new NotImplementedException(); + return 0; } public Result SetCreationTimeUtc(string path, DateTime date) diff --git a/AudioNodes/Tests/_TestBase.cs b/AudioNodes/Tests/_TestBase.cs index cffa168e..d960ae90 100644 --- a/AudioNodes/Tests/_TestBase.cs +++ b/AudioNodes/Tests/_TestBase.cs @@ -39,6 +39,7 @@ public abstract class TestBase [TestInitialize] public void TestInitialize() { + Logger.Writer = (msg) => TestContext.WriteLine(msg); this.TestPath = this.TestPath?.EmptyAsNull() ?? (IsLinux ? "~/src/ff-files/test-files/audio" : @"d:\audio\testfiles"); this.TempPath = this.TempPath?.EmptyAsNull() ?? (IsLinux ? "~/src/ff-files/temp" : @"d:\audio\temp"); this.FfmpegPath = this.FfmpegPath?.EmptyAsNull() ?? (IsLinux ? "/usr/local/bin/ffmpeg" : @"C:\utils\ffmpeg\ffmpeg.exe"); diff --git a/FileFlows.Plugin.dll b/FileFlows.Plugin.dll index 73d037fe57aa9b6617b53516605e00b4a5ff07cf..8f56f74c613a16b4d4451bac66bd9f611cd69647 100644 GIT binary patch delta 250 zcmZqp!_n}EV?qbZ`{c8)8+%%N7`OH?-H{WR+R^y+ikG=Z)11%seYI1hw^ztBEf>}> zF*Pu;Fi1`|N;R`IF*7qaPcpVNH#4;`NHZ`rNijDyNKHvgN=q`^?rzL9k&)&1OU(n* z@0c(J2fQrigf{FswJEUEARQ@%$!+rHZxx?FM zn=(yh^*3QKWiVhcVXy#_$v|ktkjh}jU5hv|L!j z!qC#tFe%y0z{1kN)X2a*EjcwY#lj%PBGJe)&A=kbB*`?<$T-fQrsAfrOTrQs4T6XZ$f5x;2q7T}i;5&{Mz#P60xkoHbHq{HstnT!78L^? zMnM!EMyY@+b_O#wG>%o#aoiBbDs4rS0@ejBwnjQF%$)fqNBoPN^ZDN2d-vXVb6?&& z*57BwkX^I_#E!QeejfHEGXcC7SRJw z<-znCOfUj0MKE!J2U8U02WIReB99NpVw$ZGlK?~z28$pLl0Xg1AkQ*hOa-VnLJ^ce z8E7jJHBbi)a2i^m^}`}#3ybLz&Ud}PSPyE```R~JOe^4EbO<$r9*l4WZop%B3a{WT z{0dA=2+fEInM-~#G7>|3jCmm`y^fKR2~=TH8nK*{5Gz(f+*rJ?S}n~ZUhF)Y0v<3M z1R#PiSOjs91Zr3Yc~Afwp$JN#EOu;Lfm9hANHtIg4R9J-pcO7z#_{QTET7t8`F%t; z2tWjV@B-ezf;c`!!xHF&yYYO|FXq!_cm)4}SxP=dLOE1HD|EoJC49QE1Y1nj`q7>Q zKiUs<&G9@c_)7K3bhGFfs^P*4&VYaU=|2K3=yD6G|!nsOA_ah z4jSPMoP#g4h^8cedYfz>1BSY)j*iF3pN+pbkuOD?BS!)PVXlw4__(! z;uKtgZ{f#u8=9oH!DJhns>2PK4Uy-@=~CQSXCV zII4D_i)u%@sh&U&)D!7Dcn(7_3@gJX(tpu%G+G{cYMe-*nM5*;Gj`{U-8qv&<3j0> z55Ln)rp+2xDuFVn)J(xUGllBWp3u1AE=;9X%{02Eai>m=`IZaFCqqDUK?LC-2PLFJ z7UV(!Y;s2wXN>($0xJDb3+Z1OctU5)6jMirn7)RA51r--GP;>5q)z>M`yOxYF3W?- zP@|NEE;cY^BeOzlZK(}1TeMtD{Wxi1;?VcJTuYW( zvLD&YV>9M#KtAHJSsZ%E^Fe;Y^I>zSizl~aDe^I|A34Bdb2!w;lUp*^k`fy>9dT6K zR4)#6adydwjN(#RW@MBd)o1piw$^V5d@@PvGRo&a4>+%EpO?01a7S|g%VE9rW79I@ zsuP_um>pPl@vtG~yNd#>|$m$m0hmVWc< z)*mx|8tO^Q$}F#v=O>NaeI=TCC+6Sv8vA3mKj`#pl8-481g;a$c0D}aXMNJ2cmCSt zD-(;fY)-Sv+q7?_w%t~!ZDN(U{oLqBRZR^W?)3demDk{A ze?TAcx^By<^zTl-&aIoi&T5$Xb?brG_ZGNok9>4tMc1DyD_D=k2HDSNzU*vlPRXoq zTkTNVJDrg*)wkt2e&UcIu`DPzH+YpKR4kE5r8%NdsU$=elpiD%=Sf3?R^{dA2GWuW|&(2rJ@XG z>UbBy^wwH^P;rp;^zphcQ=-~Dpm_UJ4hI9m^?AE&*<5qQTqbqCev7V}gE#vB$2Az3 delta 2955 zcmZwIdsGuw9tZH>gg|&oARx-}Mngc9Oo))6A}@)cP+lfHibp`%q9|Ca$o4EFhegoE z>KZ}iC|jgfbnPle3B@Xpsvs7t=x#-;B2;RzYzsbip{u*!s3q7p5O*fuI0JLbyc5f+OwVKPDOAF4sDZEr zEU6$KR>1p^1I4fnD&P~ShC|Q*C!h&hpbf4-FWiQEFbLdFh+pB~@ES}PvSbY+a0XBC z1s0SL4l$4jX^;hZun~%(6n4O0;2_k)acF`sp#!eMP3T|9a`XtrPcQ}(z${|P0_0SgLP4ABq=DUbo##_@8>LtO|(Py*$^ zRUx!c3-!Nr{pMo#P>;WdAJesDOM~>hE-rxr; zC}1%}LmZ?)24q7X6haY{K)LGewgRY16+l|3g?ea&Q_u_-jN`;~NhPLhu(A))4}QSH z0Q?C5f`v=P6bZ2~0N=!jsVP=W7vV0v1g~Xc3WZA81I^G28Oz0VWjVH(z)5IloP_p5 zEgXRpa0XhT6MCQz?!sW4VJ8wAK|KzWz>AlVCD?;Ac!3|tAOs@f4Rd@cHr|&i;0PRt z)1c=N4e$BUSb|}Y8+jzUQD~x}cBl44cj`9Q9yFflK@-N>lPJlPW+xfOcu`uC7ZpLt zo8xCm-ZTkJvZ4R&XBL?!&mxua97CDOJSv1D;7SnXPz743g?ea&Zg>LbDLj(E(i9W= z019AB3ZE)cOi2s1Fdk`&XT_B2Q8&V=6f^39n{WrrR+y0s$RGw*LD32`j&`Fs25s;i z{IWtoLbU*s1>~eQCyCmECxR`|EDqDs`ep#~1Ct?9hl zhPu?#=$6`+9>Oq;!gE*|VoSfFd#OSPknmj`X2s zI+Z{>&NxvW+M}8oxC=9>S>sHd8dtimG2C*0@=Wz7UtmEA;Sd9fkOo^vPq00mq zGF6zOH8a-d6y|6xjI|DTi^$qo&sZ=Gtu0v4r6_Caie|`TsR+jo;0QLrP+t5Dv@^jO zEWw8IlKIAVv-$JRdTpVWAHe&b9L)0i6~_5}$q$<`}cgm_x`1LKDW2 z4amDf6CR)L2)&X26ndNR>9#P^m}SWCg+s_ep$VT)1HwpS<`^?bU_x~^YJoO3z(Hi6 z8Wv$e<>_G&mQwt3 zepsp=!5#ZTyKLFlVZyFoCLGFqmei`w)u!96tse}RtiM^d^+3M(YG3%T<$v%@remyPtJ?c0`pepa08*tY71_s>4*oO8U+<$mXE$4-4m^&x)80_Vuh;@b1cMT%E1dQ)EQ zICC)lZ^gs@hyU99Dt|a){qh#!-+vhYnHy}F6FdE@k1iIRa-;pT%xyLgpEdnzZ&261 zSylIL9US+!I{I||T*>S9%+IeXVq{xH$A-4bs|u{54;-QRp;LQR3-h zMn9L)D;a$XqhHDBH!ymR(bs63*2cL^+11JD2N?Y`t@FBlQ_gLv(Oz2jL^Q=*U0Z$< zGkb~-rlp2yJLQrl tQlpc7EH(SxRNd_qpJEvB$I{1qJ_aatx!cW6EDROXPU_XVq8(cP{{eW@7u)~<