mirror of https://github.com/ErsatzTV/ErsatzTV.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
3.6 KiB
101 lines
3.6 KiB
using System.Globalization; |
|
using NCalc; |
|
using NCalc.Handlers; |
|
|
|
namespace ErsatzTV.Infrastructure.Streaming; |
|
|
|
public static class OpacityExpressionHelper |
|
{ |
|
public static void EvaluateFunction(string name, FunctionArgs args) |
|
{ |
|
switch (name) |
|
{ |
|
case "LinearFadePoints": |
|
{ |
|
if (args.Parameters.Length != 5) |
|
{ |
|
throw new ArgumentException("LinearFadePoints() requires 5 arguments."); |
|
} |
|
|
|
double time = Convert.ToDouble(args.Parameters[0].Evaluate(), CultureInfo.CurrentCulture); |
|
double start = Convert.ToDouble(args.Parameters[1].Evaluate(), CultureInfo.CurrentCulture); |
|
double peakStart = Convert.ToDouble(args.Parameters[2].Evaluate(), CultureInfo.CurrentCulture); |
|
double peakEnd = Convert.ToDouble(args.Parameters[3].Evaluate(), CultureInfo.CurrentCulture); |
|
double end = Convert.ToDouble(args.Parameters[4].Evaluate(), CultureInfo.CurrentCulture); |
|
|
|
args.Result = LinearFadePoints(time, start, peakStart, peakEnd, end); |
|
break; |
|
} |
|
case "LinearFadeDuration": |
|
{ |
|
if (args.Parameters.Length != 4) |
|
{ |
|
throw new ArgumentException("LinearFadeDuration() requires 4 arguments."); |
|
} |
|
|
|
double time = Convert.ToDouble(args.Parameters[0].Evaluate(), CultureInfo.CurrentCulture); |
|
double start = Convert.ToDouble(args.Parameters[1].Evaluate(), CultureInfo.CurrentCulture); |
|
double fadeSeconds = Convert.ToDouble(args.Parameters[2].Evaluate(), CultureInfo.CurrentCulture); |
|
double peakSeconds = Convert.ToDouble(args.Parameters[3].Evaluate(), CultureInfo.CurrentCulture); |
|
|
|
args.Result = LinearFadeDuration(time, start, fadeSeconds, peakSeconds); |
|
break; |
|
} |
|
} |
|
} |
|
|
|
private static double LinearFadePoints(double time, double start, double peakStart, double peakEnd, double end) |
|
{ |
|
if (time < start || time >= end) |
|
{ |
|
return 0; |
|
} |
|
|
|
// fade in |
|
if (time < peakStart) |
|
{ |
|
return (time - start) / (peakStart - start); |
|
} |
|
|
|
// solid |
|
if (time < peakEnd) |
|
{ |
|
return 1.0; |
|
} |
|
|
|
// fade out |
|
return (end - time) / (end - peakEnd); |
|
} |
|
|
|
private static double LinearFadeDuration(double time, double start, double fadeSeconds, double peakSeconds) |
|
{ |
|
// edge case with no fade |
|
if (fadeSeconds <= 0) |
|
{ |
|
double noFadeEnd = start + peakSeconds; |
|
return (time >= start && time < noFadeEnd) ? 1.0 : 0.0; |
|
} |
|
|
|
double peakStart = start + fadeSeconds; |
|
double peakEnd = peakStart + peakSeconds; |
|
double end = peakEnd + fadeSeconds; |
|
|
|
return LinearFadePoints(time, start, peakStart, peakEnd, end); |
|
} |
|
|
|
public static float GetOpacity( |
|
Expression expression, |
|
TimeSpan timeOfDay, |
|
TimeSpan contentTime, |
|
TimeSpan contentTotalTime, |
|
TimeSpan channelTime) |
|
{ |
|
expression.Parameters["content_seconds"] = contentTime.TotalSeconds; |
|
expression.Parameters["content_total_seconds"] = contentTotalTime.TotalSeconds; |
|
expression.Parameters["channel_seconds"] = channelTime.TotalSeconds; |
|
expression.Parameters["time_of_day_seconds"] = timeOfDay.TotalSeconds; |
|
|
|
object expressionResult = expression.Evaluate(); |
|
return Convert.ToSingle(expressionResult, CultureInfo.InvariantCulture); |
|
} |
|
}
|
|
|