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",