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.
82 lines
2.8 KiB
82 lines
2.8 KiB
using ErsatzTV.Core.Graphics; |
|
using ErsatzTV.Core.Interfaces.Streaming; |
|
using Microsoft.Extensions.Logging; |
|
using NCalc; |
|
using SkiaSharp; |
|
|
|
namespace ErsatzTV.Infrastructure.Streaming.Graphics; |
|
|
|
public class ImageElement(ImageGraphicsElement imageGraphicsElement, ILogger logger) : ImageElementBase |
|
{ |
|
private Option<Expression> _maybeOpacityExpression; |
|
private float _opacity; |
|
|
|
public override async Task InitializeAsync(GraphicsEngineContext context, CancellationToken cancellationToken) |
|
{ |
|
try |
|
{ |
|
if (!string.IsNullOrWhiteSpace(imageGraphicsElement.OpacityExpression)) |
|
{ |
|
var expression = new Expression(imageGraphicsElement.OpacityExpression); |
|
expression.EvaluateFunction += OpacityExpressionHelper.EvaluateFunction; |
|
_maybeOpacityExpression = expression; |
|
} |
|
else |
|
{ |
|
_opacity = (imageGraphicsElement.OpacityPercent ?? 100) / 100.0f; |
|
} |
|
|
|
ZIndex = imageGraphicsElement.ZIndex ?? 0; |
|
|
|
foreach (Expression expression in _maybeOpacityExpression) |
|
{ |
|
expression.EvaluateFunction += OpacityExpressionHelper.EvaluateFunction; |
|
} |
|
|
|
await LoadImage( |
|
context.SquarePixelFrameSize, |
|
context.FrameSize, |
|
imageGraphicsElement.Image, |
|
imageGraphicsElement.Location, |
|
imageGraphicsElement.Scale, |
|
imageGraphicsElement.ScaleWidthPercent, |
|
imageGraphicsElement.HorizontalMarginPercent, |
|
imageGraphicsElement.VerticalMarginPercent, |
|
imageGraphicsElement.PlaceWithinSourceContent, |
|
cancellationToken); |
|
} |
|
catch (Exception ex) |
|
{ |
|
IsFinished = true; |
|
logger.LogWarning(ex, "Failed to initialize image element; will disable for this content"); |
|
} |
|
} |
|
|
|
public override ValueTask<Option<PreparedElementImage>> PrepareImage( |
|
TimeSpan timeOfDay, |
|
TimeSpan contentTime, |
|
TimeSpan contentTotalTime, |
|
TimeSpan channelTime, |
|
CancellationToken cancellationToken) |
|
{ |
|
float opacity = _opacity; |
|
foreach (Expression expression in _maybeOpacityExpression) |
|
{ |
|
opacity = OpacityExpressionHelper.GetOpacity( |
|
expression, |
|
timeOfDay, |
|
contentTime, |
|
contentTotalTime, |
|
channelTime); |
|
} |
|
|
|
if (opacity == 0) |
|
{ |
|
return ValueTask.FromResult(Option<PreparedElementImage>.None); |
|
} |
|
|
|
SKBitmap frameForTimestamp = GetFrameForTimestamp(contentTime); |
|
return ValueTask.FromResult( |
|
Optional(new PreparedElementImage(frameForTimestamp, Location, opacity, ZIndex, false))); |
|
} |
|
}
|
|
|