diff --git a/Apprise/Apprise.csproj b/Apprise/Apprise.csproj index 7503db9d..5abb4ad4 100644 Binary files a/Apprise/Apprise.csproj and b/Apprise/Apprise.csproj differ diff --git a/Apprise/Plugin.cs b/Apprise/Plugin.cs index bdd5705f..ef22b601 100644 Binary files a/Apprise/Plugin.cs and b/Apprise/Plugin.cs differ diff --git a/BasicNodes/BasicNodes.csproj b/BasicNodes/BasicNodes.csproj index e5867bad..b94382d4 100644 Binary files a/BasicNodes/BasicNodes.csproj and b/BasicNodes/BasicNodes.csproj differ diff --git a/BasicNodes/Plugin.cs b/BasicNodes/Plugin.cs index 6a362385..36f467f3 100644 Binary files a/BasicNodes/Plugin.cs and b/BasicNodes/Plugin.cs differ diff --git a/ChecksumNodes/ChecksumNodes.csproj b/ChecksumNodes/ChecksumNodes.csproj index 7d6bdae7..87c6a07a 100644 Binary files a/ChecksumNodes/ChecksumNodes.csproj and b/ChecksumNodes/ChecksumNodes.csproj differ diff --git a/ChecksumNodes/Plugin.cs b/ChecksumNodes/Plugin.cs index e8664e32..570092ae 100644 Binary files a/ChecksumNodes/Plugin.cs and b/ChecksumNodes/Plugin.cs differ diff --git a/CollectionNodes/CollectionNodes.csproj b/CollectionNodes/CollectionNodes.csproj index 3d7f1d2a..71dc3d42 100644 Binary files a/CollectionNodes/CollectionNodes.csproj and b/CollectionNodes/CollectionNodes.csproj differ diff --git a/CollectionNodes/Plugin.cs b/CollectionNodes/Plugin.cs index a3843573..f4c758ae 100644 Binary files a/CollectionNodes/Plugin.cs and b/CollectionNodes/Plugin.cs differ diff --git a/DiscordNodes/DiscordNodes.csproj b/DiscordNodes/DiscordNodes.csproj index 3e7bb035..cb20b378 100644 Binary files a/DiscordNodes/DiscordNodes.csproj and b/DiscordNodes/DiscordNodes.csproj differ diff --git a/DiscordNodes/Plugin.cs b/DiscordNodes/Plugin.cs index 843d2583..b07e443d 100644 Binary files a/DiscordNodes/Plugin.cs and b/DiscordNodes/Plugin.cs differ diff --git a/EmailNodes/EmailNodes.csproj b/EmailNodes/EmailNodes.csproj index 672cd611..918cbb79 100644 Binary files a/EmailNodes/EmailNodes.csproj and b/EmailNodes/EmailNodes.csproj differ diff --git a/EmailNodes/Plugin.cs b/EmailNodes/Plugin.cs index 26fae782..7f400544 100644 Binary files a/EmailNodes/Plugin.cs and b/EmailNodes/Plugin.cs differ diff --git a/Emby/Emby.csproj b/Emby/Emby.csproj index ddb2d710..ee308ac7 100644 Binary files a/Emby/Emby.csproj and b/Emby/Emby.csproj differ diff --git a/Emby/Plugin.cs b/Emby/Plugin.cs index 6e4bea47..cb6cc7e9 100644 Binary files a/Emby/Plugin.cs and b/Emby/Plugin.cs differ diff --git a/Gotify/Gotify.csproj b/Gotify/Gotify.csproj index a5e437fb..25c2ef22 100644 Binary files a/Gotify/Gotify.csproj and b/Gotify/Gotify.csproj differ diff --git a/Gotify/Plugin.cs b/Gotify/Plugin.cs index f46455e4..6e547a5f 100644 Binary files a/Gotify/Plugin.cs and b/Gotify/Plugin.cs differ diff --git a/ImageNodes/ImageNodes.csproj b/ImageNodes/ImageNodes.csproj index d5ff868e..786a21cf 100644 Binary files a/ImageNodes/ImageNodes.csproj and b/ImageNodes/ImageNodes.csproj differ diff --git a/ImageNodes/Plugin.cs b/ImageNodes/Plugin.cs index d9516c4c..f0dc2da3 100644 Binary files a/ImageNodes/Plugin.cs and b/ImageNodes/Plugin.cs differ diff --git a/MetaNodes/MetaNodes.csproj b/MetaNodes/MetaNodes.csproj index 6dcb2081..41ab370e 100644 Binary files a/MetaNodes/MetaNodes.csproj and b/MetaNodes/MetaNodes.csproj differ diff --git a/MetaNodes/Plugin.cs b/MetaNodes/Plugin.cs index 13dbe9ca..855b8c84 100644 Binary files a/MetaNodes/Plugin.cs and b/MetaNodes/Plugin.cs differ diff --git a/MusicNodes/MusicNodes.csproj b/MusicNodes/MusicNodes.csproj index 58519bf9..02f22f3f 100644 Binary files a/MusicNodes/MusicNodes.csproj and b/MusicNodes/MusicNodes.csproj differ diff --git a/MusicNodes/Plugin.cs b/MusicNodes/Plugin.cs index befd9ff7..9b52da9b 100644 Binary files a/MusicNodes/Plugin.cs and b/MusicNodes/Plugin.cs differ diff --git a/Plex/Plex.csproj b/Plex/Plex.csproj index 7bdcdff9..0f0e5548 100644 Binary files a/Plex/Plex.csproj and b/Plex/Plex.csproj differ diff --git a/Plex/Plugin.cs b/Plex/Plugin.cs index 6ba42f58..44fd16cb 100644 Binary files a/Plex/Plugin.cs and b/Plex/Plugin.cs differ diff --git a/VideoNodes/FfmpegBuilderNodes/FfmpegBuilderCustomParameters.cs b/VideoNodes/FfmpegBuilderNodes/FfmpegBuilderCustomParameters.cs new file mode 100644 index 00000000..e8ce1d3d --- /dev/null +++ b/VideoNodes/FfmpegBuilderNodes/FfmpegBuilderCustomParameters.cs @@ -0,0 +1,68 @@ +using FileFlows.VideoNodes.FfmpegBuilderNodes.Models; + +namespace FileFlows.VideoNodes.FfmpegBuilderNodes; + +/// +/// Node that adds custom parameters to the FFMPEG Builder +/// +public class FfmpegBuilderCustomParameters : FfmpegBuilderNode +{ + /// + /// Gets the Help URL for this node + /// + public override string HelpUrl => "https://docs.fileflows.com/plugins/video-nodes/ffmpeg-builder/custom-parameters"; + + /// + /// Gets the icon for this node + /// + public override string Icon => "fas fa-plus-square"; + + /// + /// Gets the number of outputs for this node + /// + public override int Outputs => 1; + + + /// + /// Gets or sets the parameters to add + /// + [TextVariable(1)] + [Required] + public string Parameters { get; set; } + + /// + /// Gets or sets if the video should be forcable encoded when these parameters are added + /// + [Boolean(2)] + [DefaultValue(true)] + public bool ForceEncode { get; set; } + + + /// + /// Executes the node + /// + /// the node parameters + /// the output number to execute next + public override int Execute(NodeParameters args) + { + string parameters = args.ReplaceVariables(Parameters); + if (string.IsNullOrWhiteSpace(parameters)) + return 1; + + string[] split = Regex.Split(parameters, "(\"[^\"]+\"|[^\\s\"]+)"); + foreach(var parameter in split) + { + if (string.IsNullOrWhiteSpace(parameter)) + continue; + + string actual = parameter; + if (parameter.StartsWith("\"") && parameter.EndsWith("\"")) + actual = parameter[1..^1]; + this.Model.CustomParameters.Add(actual); + } + + this.Model.ForceEncode = ForceEncode; + + return 1; + } +} diff --git a/VideoNodes/FfmpegBuilderNodes/FfmpegBuilderExecutor.cs b/VideoNodes/FfmpegBuilderNodes/FfmpegBuilderExecutor.cs index 00132b28..a6eceefe 100644 --- a/VideoNodes/FfmpegBuilderNodes/FfmpegBuilderExecutor.cs +++ b/VideoNodes/FfmpegBuilderNodes/FfmpegBuilderExecutor.cs @@ -24,6 +24,10 @@ namespace FileFlows.VideoNodes.FfmpegBuilderNodes List ffArgs = new List(); ffArgs.AddRange(new[] { "-strict", "-2" }); // allow experimental stuff ffArgs.AddRange(new[] { "-fflags", "+genpts" }); //Generate missing PTS if DTS is present. + + if(model.CustomParameters?.Any() == true) + ffArgs.AddRange(model.CustomParameters); + bool hasChange = false; int actualIndex = 0; int currentType = 0; @@ -53,7 +57,7 @@ namespace FileFlows.VideoNodes.FfmpegBuilderNodes ffArgs.AddRange(model.MetadataParameters); } - if (hasChange == false && (string.IsNullOrWhiteSpace(model.Extension) || args.WorkingFile.ToLower().EndsWith("." + model.Extension.ToLower()))) + if (model.ForceEncode == false && hasChange == false && (string.IsNullOrWhiteSpace(model.Extension) || args.WorkingFile.ToLower().EndsWith("." + model.Extension.ToLower()))) return 2; // nothing to do string extension = model.Extension?.EmptyAsNull() ?? "mkv"; diff --git a/VideoNodes/FfmpegBuilderNodes/Models/FfmpegModel.cs b/VideoNodes/FfmpegBuilderNodes/Models/FfmpegModel.cs index b52aecd1..0776c511 100644 --- a/VideoNodes/FfmpegBuilderNodes/Models/FfmpegModel.cs +++ b/VideoNodes/FfmpegBuilderNodes/Models/FfmpegModel.cs @@ -37,6 +37,22 @@ set => _InputFiles = value ?? new List(); } + private List _CustomParameters = new List(); + + /// + /// Gets or sets custom parameters to use in the FFMPEG Builder + /// + public List CustomParameters + { + get => _CustomParameters; + set => _CustomParameters = value ?? new List(); + } + + /// + /// Gets or sets if the builder should forcable execute even if nothing appears to have changed + /// + public bool ForceEncode { get; set; } + /// /// Gets or sets the video information for this video file /// diff --git a/VideoNodes/Plugin.cs b/VideoNodes/Plugin.cs index f8a6d4ba..82aa1b3b 100644 Binary files a/VideoNodes/Plugin.cs and b/VideoNodes/Plugin.cs differ diff --git a/VideoNodes/Tests/FfmpegBuilderTests/FfmpegBuilder_BasicTests.cs b/VideoNodes/Tests/FfmpegBuilderTests/FfmpegBuilder_BasicTests.cs index 68a94657..87197c8d 100644 --- a/VideoNodes/Tests/FfmpegBuilderTests/FfmpegBuilder_BasicTests.cs +++ b/VideoNodes/Tests/FfmpegBuilderTests/FfmpegBuilder_BasicTests.cs @@ -1056,6 +1056,39 @@ public class FfmpegBuilder_BasicTests string log = logger.ToString(); Assert.AreEqual(1, result); } + + + + [TestMethod] + public void FfmpegBuilder_CustomParameters() + { + const string file = @"D:\videos\testfiles\basic.mkv"; + var logger = new TestLogger(); + const string ffmpeg = @"C:\utils\ffmpeg\ffmpeg.exe"; + var vi = new VideoInfoHelper(ffmpeg, logger); + var vii = vi.Read(file); + var args = new NodeParameters(file, logger, false, string.Empty); + args.GetToolPathActual = (string tool) => ffmpeg; + args.TempPath = @"D:\videos\temp"; + args.Parameters.Add("VideoInfo", vii); + + FfmpegBuilderStart ffStart = new(); + ffStart.PreExecute(args); + Assert.AreEqual(1, ffStart.Execute(args)); + + FfmpegBuilderCustomParameters ffCustom = new(); + ffCustom.Parameters = "this is a \"testing bobby drake\" blah"; + ffCustom.ForceEncode = true; + ffCustom.PreExecute(args); + ffCustom.Execute(args); + + FfmpegBuilderExecutor ffExecutor = new(); + ffExecutor.PreExecute(args); + int result = ffExecutor.Execute(args); + + string log = logger.ToString(); + Assert.IsTrue(log.Contains("this is a \"testing bobby drake\" blah")); + } } #endif \ No newline at end of file diff --git a/VideoNodes/VideoNodes.csproj b/VideoNodes/VideoNodes.csproj index 6562e481..94d1ee31 100644 Binary files a/VideoNodes/VideoNodes.csproj and b/VideoNodes/VideoNodes.csproj differ diff --git a/VideoNodes/VideoNodes.en.json b/VideoNodes/VideoNodes.en.json index 03558d94..da936194 100644 --- a/VideoNodes/VideoNodes.en.json +++ b/VideoNodes/VideoNodes.en.json @@ -329,6 +329,19 @@ "2": "No commercials detected" } }, + "FfmpegBuilderCustomParameters": { + "Label": "FFMPEG Builder: Custom Parameters", + "Description": "Lets you add custom parameters to the FFMPEG Builder for execution", + "Outputs": { + "1": "Parameters added" + }, + "Fields": { + "Parameters": "Parameters", + "Parameters-Help": "The parameters to add to the FFMPEG Builder for execution", + "ForceEncode": "Force Encode", + "ForceEncode-Help": "If this should force the FFMPEG Builder Executor to always execute even if no changes are detected that would usually require the executor to run." + } + }, "FfmpegBuilderHdrToSdr": { "Label": "FFMPEG Builder: HDR to SDR", "Description": "Checks if a video stream is HDR and if it is updates the FFMPEG Builder to convert it to SDR",