fixing function node when variables use ?. notation

This commit is contained in:
reven
2022-01-19 16:19:19 +13:00
parent 88df5b713d
commit 7379e24965
2 changed files with 176 additions and 55 deletions

View File

@@ -33,71 +33,52 @@ namespace FileFlows.BasicNodes.Functions
if (string.IsNullOrEmpty(Code))
return -1; // no code, flow cannot continue doesnt know what to do
args.Logger?.DLog("Code: ", Environment.NewLine + new string('=', 40) + Environment.NewLine + Code + Environment.NewLine + new string('=', 40));
long fileSize = 0;
var fileInfo = new FileInfo(args.WorkingFile);
if(fileInfo.Exists)
fileSize = fileInfo.Length;
// replace Variables. with dictionary notation
string tcode = Code;
foreach (string k in args.Variables.Keys.OrderByDescending(x => x.Length))
{
tcode = tcode.Replace("Variables." + k, "Variables['" + k + "']");
}
var sb = new StringBuilder();
var log = new
{
ILog = new LogDelegate(args.Logger.ILog),
DLog = new LogDelegate(args.Logger.DLog),
WLog = new LogDelegate(args.Logger.WLog),
ELog = new LogDelegate(args.Logger.ELog),
};
var engine = new Engine(options =>
{
options.LimitMemory(4_000_000);
options.MaxStatements(500);
})
.SetValue("Logger", args.Logger)
.SetValue("Variables", args.Variables)
.SetValue("Flow", args);
try
{
args.Logger?.DLog("Code: ", Environment.NewLine + new string('=', 40) + Environment.NewLine + Code + Environment.NewLine + new string('=', 40));
long fileSize = 0;
var fileInfo = new FileInfo(args.WorkingFile);
if (fileInfo.Exists)
fileSize = fileInfo.Length;
// replace Variables. with dictionary notation
string tcode = Code;
foreach (string k in args.Variables.Keys.OrderByDescending(x => x.Length))
{
// replace Variables.Key or Variables?.Key?.Subkey etc to just the variable
// so Variables.file?.Orig.Name, will be replaced to Variables["file.Orig.Name"]
// since its just a dictionary key value
string keyRegex = @"Variables(\?)?\." + k.Replace(".", @"(\?)?\.");
tcode = Regex.Replace(tcode, keyRegex, "Variables['" + k + "']");
}
var sb = new StringBuilder();
var log = new
{
ILog = new LogDelegate(args.Logger.ILog),
DLog = new LogDelegate(args.Logger.DLog),
WLog = new LogDelegate(args.Logger.WLog),
ELog = new LogDelegate(args.Logger.ELog),
};
var engine = new Engine(options =>
{
options.LimitMemory(4_000_000);
options.MaxStatements(500);
})
.SetValue("Logger", args.Logger)
.SetValue("Variables", args.Variables)
.SetValue("Flow", args);
var result = int.Parse(engine.Evaluate(tcode).ToObject().ToString());
return result;
}
catch (Exception ex)
{
args.Logger.ELog("Failed executing function: " + ex.Message);
args.Logger?.ELog("Failed executing function: " + ex.Message + Environment.NewLine + ex.StackTrace);
return -1;
}
}
//private Dictionary<string, object> ExplodeVariables(Dictionary<string, object> input)
//{
// Dictionary<string, object> result = new();
// foreach(var key in input.Keys)
// {
// if(key.IndexOf(".") > 0)
// {
// // folder.Date.Year
// // folder.Date.Month
// // folder.Date.Date
// //bk = Date
// string bk = key.Substring(0, key.IndexOf("."));
// if(result.ContainsKey(bk) == false)
// result.Add(bk, new Dictionary<string, object>());
// Dictionary<string, object> bkdict = (Dictionary<string, object>)result[bk];
// // nk = Year
// string nk = key.Substring(key.IndexOf(".") + 1);
// bkdict[]
// }
// }
// return result;
//}
}
}

View File

@@ -176,6 +176,7 @@ return 1";
Assert.IsTrue(args.Parameters.ContainsKey("batman"));
Assert.AreEqual(args.Parameters["batman"].ToString(), "1989");
}
[TestMethod]
public void Function_Flow_GetDirectorySize()
{
@@ -208,6 +209,7 @@ return 0;
var result = pm.Execute(args);
Assert.AreEqual(2, result);
}
[TestMethod]
public void Function_Flow_ExecuteFfmpeg()
{
@@ -248,6 +250,144 @@ return 1;
var result = pm.Execute(args);
Assert.AreEqual(1, result);
}
[TestMethod]
public void Function_Flow_NullabeVI()
{
Function pm = new Function();
var logger = new TestLogger();
var args = new FileFlows.Plugin.NodeParameters(@"c:\test\sdfsdfdsvfdcxdsf.mkv", logger, false, string.Empty);
foreach(var kv in new Dictionary<string, object>()
{
{ "vi.Video.Codec", "hevc" },
{ "vi.Audio.Codec", "ac3" },
{ "vi.Audio.Codecs", "ac3,aac"},
{ "vi.Audio.Language", "eng" },
{ "vi.Audio.Languages", "eng, mao" },
{ "vi.Resolution", "1080p" },
{ "vi.Duration", 1800 },
{ "vi.VideoInfo", new
{
Bitrate = 10_000_000,
VideoStreams = new List<object> {
new { Width = 1920, Height = 1080 }
}
}
},
{ "vi.Width", 1920 },
{ "vi.Height", 1080 },
})
{
args.Variables.Add(kv.Key, kv.Value);
};
pm.Code = @"
// get the first video stream, likely the only one
let video = Variables.vi?.VideoInfo?.VideoStreams[0];
if (!video)
return -1; // no video streams detected
if (video.Width > 1920)
{
// down scale to 1920 and encodes using NVIDIA
// then add a 'Video Encode' node and in that node
// set
// 'Video Codec' to 'hevc'
// 'Video Codec Parameters' to '{EncodingParameters}'
Logger.ILog(`Need to downscale from ${video.Width}x${video.Height}`);
Variables.EncodingParameters = '-vf scale=1920:-2:flags=lanczos -c:v hevc_nvenc -preset hq -crf 23'
return 1;
}
Logger.ILog('Do not need to downscale');
return 2;";
var result = pm.Execute(args);
Assert.IsTrue(result > 0);
}
[TestMethod]
public void Function_Flow_NullabeVI_2()
{
Function pm = new Function();
var logger = new TestLogger();
var args = new FileFlows.Plugin.NodeParameters(@"c:\test\sdfsdfdsvfdcxdsf.mkv", logger, false, string.Empty);
foreach (var kv in new Dictionary<string, object>()
{
{ "vi.Video.Codec", "hevc" },
{ "vi.Audio.Codec", "ac3" },
{ "vi.Audio.Codecs", "ac3,aac"},
{ "vi.Audio.Language", "eng" },
{ "vi.Audio.Languages", "eng, mao" },
{ "vi.Resolution", "1080p" },
{ "vi.Duration", 1800 },
{ "vi.VideoInfo", new
{
Bitrate = 10_000_000,
VideoStreams = new List<object> {
new { Width = 1920, Height = 1080 }
},
AudioStreams = new List<object> {
new { Bitrate = 1_000 }
}
}
},
{ "vi.Width", 1920 },
{ "vi.Height", 1080 },
})
{
args.Variables.Add(kv.Key, kv.Value);
};
pm.Code = @"
// check if the bitrate for a video is over a certain amount
let MAX_BITRATE = 3_000_000; // bitrate is 3,000 KBps
let vi = Variables.vi?.VideoInfo;
if(!vi)
return -1; // no video information found
// get the video stream
let bitrate = vi.VideoStreams[0]?.Bitrate;
if(!bitrate)
{
// video stream doesn't have bitrate information
// need to use the overall bitrate
let overall = vi.Bitrate;
if(!overall)
return 0; // couldn't get overall bitrate either
// overall bitrate includes all audio streams, so we try and subtrack those
let calculated = overall;
if(vi.AudioStreams?.length) // check there are audio streams
{
for(let audio of vi.AudioStreams)
{
if(audio.Bitrate > 0)
calculated -= audio.Bitrate;
else{
// audio doesn't have bitrate either, so we just subtract 5% of the original bitrate
// this is a guess, but it should get us close
calculated -= (overall * 0.05);
}
}
}
bitrate = calculated;
}
// check if the bitrate is over the maximum bitrate
if(bitrate > MAX_BITRATE)
return 1; // it is, so call output 1
return 2; // it isn't so call output 2";
var result = pm.Execute(args);
Assert.IsTrue(result > 0);
}
}
}