Files
FileFlowsPlugins/VideoNodes/FfmpegBuilderNodes/FfmpegBuilderNode.cs
2024-04-19 11:11:43 +12:00

162 lines
6.3 KiB
C#

using FileFlows.Plugin;
using FileFlows.VideoNodes.FfmpegBuilderNodes.Models;
namespace FileFlows.VideoNodes.FfmpegBuilderNodes
{
public abstract class FfmpegBuilderNode: EncodingNode
{
internal const string MODEL_KEY = "FfmpegBuilderModel";
/// <summary>
/// Gets the number of inputs
/// </summary>
public override int Inputs => 1;
/// <summary>
/// Gets the number of outputs
/// </summary>
public override int Outputs => 1;
/// <summary>
/// Gets the icon
/// </summary>
public override string Icon => "far fa-file-video";
/// <summary>
/// Gets the flow element type
/// </summary>
public override FlowElementType Type => FlowElementType.BuildPart;
/// <summary>
/// Gets the help URL
/// </summary>
public override string HelpUrl => "https://fileflows.com/docs/plugins/video-nodes/ffmpeg-builder";
/// <summary>
/// Runs any code that needs to run before the execution code
/// E.g. loads any variables that the Execute will use
/// </summary>
/// <param name="args">the node parameters</param>
/// <returns>true if successful, otherwise false and will fail the flow</returns>
/// <exception cref="Exception">throw if the video is not initialized</exception>
public override bool PreExecute(NodeParameters args)
{
if (base.PreExecute(args) == false)
return false;
if(this is FfmpegBuilderStart == false && Model == null)
throw new Exception("FFMPEG Builder Model not set, you must add and use the \"FFMPEG Builder Start\" flow element first");
if (this is FfmpegBuilderStart == false)
{
if (Model.VideoInfo == null)
throw new Exception("FFMPEG Builder VideoInfo is null");
string header = "------------------------ Starting FFmpeg Builder Model ------------------------";
args.Logger?.ILog(header);
foreach (var stream in Model.VideoStreams ?? new List<FfmpegVideoStream>())
{
string line = "| Video Stream: " + stream;
args.Logger?.ILog(line + new string(' ', Math.Max(1, header.Length - line.Length - 1)) + '|');
}
foreach (var stream in Model.AudioStreams ?? new List<FfmpegAudioStream>())
{
string line = "| Audio Stream: " + stream;
args.Logger?.ILog(line + new string(' ', Math.Max(1, header.Length - line.Length - 1)) + '|');
}
foreach (var stream in Model.SubtitleStreams ?? new List<FfmpegSubtitleStream>())
{
string line = "| Subtitle Stream: " + stream;
args.Logger?.ILog(line + new string(' ', Math.Max(1, header.Length - line.Length - 1)) + '|');
}
args.Logger?.ILog(new string('-', header.Length));
}
return true;
}
public override int Execute(NodeParameters args)
{
return 1;
}
internal FfmpegModel GetModel() => this.Model;
protected FfmpegModel Model
{
get
{
if (Args.Variables.TryGetValue(MODEL_KEY, out var variable))
return variable as FfmpegModel;
return null;
}
set
{
if (Args.Variables.ContainsKey(MODEL_KEY))
{
if (value == null)
Args.Variables.Remove(MODEL_KEY);
else
Args.Variables[MODEL_KEY] = value;
}
else if(value != null)
Args.Variables.Add(MODEL_KEY, value);
}
}
protected string[] SplitCommand(string cmd)
{
return Regex.Matches(cmd, @"[\""].+?[\""]|[^ ]+")
.Cast<Match>()
.Select(x => x.Value.Trim('"'))
.ToArray();
}
protected bool PatternMatches2(string pattern, int index, FfmpegStream stream, bool notMatching = false)
{
bool match;
var matchLessThan = Regex.Match(pattern, @"^[\s]*<[\s]*([\d]+)[\s]*$");
var matchLessThanEqual = Regex.Match(pattern, @"^[\s]*<=[\s]*([\d]+)[\s]*$");
var matchGreaterThan = Regex.Match(pattern, @"^[\s]*>[\s]*([\d]+)[\s]*$");
var matchGreaterThanEqual = Regex.Match(pattern, @"^[\s]*>=[\s]*([\d]+)[\s]*$");
if (matchLessThan.Success)
{
int lessThanIndex = int.Parse(matchLessThan.Groups[1].Value);
match = index < lessThanIndex;
}
else if (matchLessThanEqual.Success)
{
int lessThanIndex = int.Parse(matchLessThanEqual.Groups[1].Value);
match = index <= lessThanIndex;
}
else if (matchGreaterThan.Success)
{
int greaterThanIndex = int.Parse(matchGreaterThan.Groups[1].Value);
match = index > greaterThanIndex;
}
else if (matchGreaterThanEqual.Success)
{
int greaterThanIndex = int.Parse(matchGreaterThanEqual.Groups[1].Value);
match = index >= greaterThanIndex;
}
else
{
string matchString;
if (stream is FfmpegAudioStream audio)
matchString = audio.Stream.Title + ":" + audio.Stream.Language + ":" + audio.Stream.Codec;
else if (stream is FfmpegVideoStream video)
matchString = video.Stream.Title + ":" + video.Stream.Codec;
else if (stream is FfmpegSubtitleStream subtitle)
matchString = subtitle.Stream.Title + ":" + subtitle.Stream.Language + ":" + subtitle.Stream.Codec;
else
return false;
Args.Logger?.ILog($"Track [{index}] test string: {matchString}");
match = new Regex(pattern, RegexOptions.IgnoreCase).IsMatch(matchString);
}
if (notMatching)
match = !match;
return match;
}
}
}