mirror of
https://github.com/revenz/FileFlowsPlugins.git
synced 2025-12-30 19:29:49 -06:00
136 lines
4.6 KiB
C#
136 lines
4.6 KiB
C#
namespace FileFlows.VideoNodes;
|
|
|
|
/// <summary>
|
|
/// Flow element to test if a video is interlaced
|
|
/// </summary>
|
|
public class VideoIsInterlaced : VideoNode
|
|
{
|
|
/// <summary>
|
|
/// Gets the number of inputs
|
|
/// </summary>
|
|
public override int Inputs => 1;
|
|
/// <summary>
|
|
/// Gets the number of outputs
|
|
/// </summary>
|
|
public override int Outputs => 2;
|
|
/// <summary>
|
|
/// Gets the type of flow element
|
|
/// </summary>
|
|
public override FlowElementType Type => FlowElementType.Logic;
|
|
/// <summary>
|
|
/// Gets the icon
|
|
/// </summary>
|
|
public override string Icon => "fas fa-question";
|
|
/// <summary>
|
|
/// Gets the help URL
|
|
/// </summary>
|
|
public override string HelpUrl => "https://fileflows.com/docs/plugins/video-nodes/logical-nodes/video-is-interlaced";
|
|
|
|
/// <summary>
|
|
/// Gets or sets the threshold
|
|
/// </summary>
|
|
[Range(1, 100)]
|
|
[Slider(1)]
|
|
[DefaultValue(10)]
|
|
public int Threshold { get; set; }
|
|
|
|
/// <summary>
|
|
/// Executes the flow element
|
|
/// </summary>
|
|
/// <param name="args">the arguments</param>
|
|
/// <returns>the output to call next</returns>
|
|
public override int Execute(NodeParameters args)
|
|
{
|
|
string ffmpeg = args.GetToolPath("FFmpeg");
|
|
if (string.IsNullOrEmpty(ffmpeg))
|
|
{
|
|
args.Logger?.ELog("FFmpeg tool not found.");
|
|
return 2;
|
|
}
|
|
|
|
var localFile = args.FileService.GetLocalPath(args.WorkingFile);
|
|
if (localFile.Failed(out string error))
|
|
{
|
|
args.FailureReason = "Failed to get local file: " + error;
|
|
args.Logger?.ELog(args.FailureReason);
|
|
return -1;
|
|
}
|
|
|
|
var ffOutput = args.Execute(new()
|
|
{
|
|
Command = ffmpeg,
|
|
Silent = true,
|
|
ArgumentList = new[]
|
|
{
|
|
"-hide_banner",
|
|
"-i", localFile.Value,
|
|
"-vf", "idet",
|
|
"-f", "null", "-"
|
|
}
|
|
});
|
|
|
|
if (string.IsNullOrEmpty(ffOutput.StandardOutput))
|
|
{
|
|
args.Logger?.ELog("Failed to get standard output from FFmpeg");
|
|
return 2;
|
|
}
|
|
|
|
bool isInterlaced = IsVideoInterlaced(args.Logger, ffOutput.StandardOutput, Math.Max(Threshold, 1));
|
|
args.Logger?.ILog("Is interlaced: " + isInterlaced);
|
|
return isInterlaced ? 1 : 2;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines if a video is interlaced based on FFmpeg output.
|
|
/// </summary>
|
|
/// <param name="ffmpegOutput">The FFmpeg output as a string.</param>
|
|
/// <param name="interlaceThreshold">An optional threshold for the number of interlaced frames to consider.</param>
|
|
/// <returns>True if the video is interlaced, false if it's not.</returns>
|
|
public static bool IsVideoInterlaced(ILogger logger, string ffmpegOutput, int interlaceThreshold = 10)
|
|
{
|
|
// Define regular expressions to match interlaced and progressive frame counts
|
|
Regex tffRegex = new Regex(@"TFF:[\s]*(\d+)");
|
|
Regex bffRegex = new Regex(@"BFF:[\s]*(\d+)");
|
|
Regex progressiveRegex = new Regex(@"Progressive:[\s]*(\d+)");
|
|
|
|
int tffCount = 0;
|
|
int bffCount = 0;
|
|
int progressiveCount = 0;
|
|
|
|
// Use regular expressions to extract counts of interlaced and progressive frames
|
|
MatchCollection tffMatches = tffRegex.Matches(ffmpegOutput);
|
|
MatchCollection bffMatches = bffRegex.Matches(ffmpegOutput);
|
|
MatchCollection progressiveMatches = progressiveRegex.Matches(ffmpegOutput);
|
|
|
|
foreach (Match match in tffMatches)
|
|
{
|
|
tffCount += int.Parse(match.Groups[1].Value);
|
|
}
|
|
|
|
foreach (Match match in bffMatches)
|
|
{
|
|
bffCount += int.Parse(match.Groups[1].Value);
|
|
}
|
|
|
|
foreach (Match match in progressiveMatches)
|
|
{
|
|
progressiveCount += int.Parse(match.Groups[1].Value);
|
|
}
|
|
|
|
// Calculate the total count of interlaced frames
|
|
int totalInterlacedCount = tffCount + bffCount;
|
|
|
|
int totalFrames = totalInterlacedCount + progressiveCount;
|
|
float percent = ((float)totalInterlacedCount) / totalFrames * 100f;
|
|
|
|
logger?.ILog("Interlaced threshold percentage: " + interlaceThreshold);
|
|
logger?.ILog("Total Interlaced Frames: " + totalInterlacedCount);
|
|
logger?.ILog("Total Progressive Frames: " + progressiveCount);
|
|
logger?.ILog("Total Frames: " + totalFrames);
|
|
logger?.ILog("Interlaced Percent: " + percent);
|
|
|
|
// Check if the total count of interlaced frames exceeds the threshold
|
|
return percent >= interlaceThreshold;
|
|
}
|
|
}
|