From a9d1bdeae019e866822cb220d37d74b8628e0159 Mon Sep 17 00:00:00 2001 From: Jason Dove <1695733+jasongdove@users.noreply.github.com> Date: Mon, 15 Jun 2026 16:45:22 -0500 Subject: [PATCH] feat: add epg_entries support to image graphics elements --- CHANGELOG.md | 1 + .../Graphics/ImageGraphicsElement.cs | 3 ++ .../Streaming/GraphicsEngineContext.cs | 5 +++- .../Graphics/GraphicsElementLoader.cs | 29 ++++++++++++++----- .../Streaming/Graphics/GraphicsEngine.cs | 2 +- 5 files changed, 30 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5a03d1be..159aa2511 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - A config file named `default.json` will apply to all channels using the Next engine - A config file named `{channel_number}.json` (e.g. `1.json`) will apply to the channel with that number - Channel overlays will override values from the default overlay which will override values from the FFmpeg Profile +- Add `epg_entries` support to image graphics elements ### Fixed - Fix HLS Direct playback when JWT auth is also used diff --git a/ErsatzTV.Core/Graphics/ImageGraphicsElement.cs b/ErsatzTV.Core/Graphics/ImageGraphicsElement.cs index f71e3d9f0..ac75e1e3f 100644 --- a/ErsatzTV.Core/Graphics/ImageGraphicsElement.cs +++ b/ErsatzTV.Core/Graphics/ImageGraphicsElement.cs @@ -30,6 +30,9 @@ public class ImageGraphicsElement : BaseGraphicsElement [YamlMember(Alias = "z_index", ApplyNamingConventions = false)] public int? ZIndex { get; set; } + [YamlMember(Alias = "epg_entries", ApplyNamingConventions = false)] + public int EpgEntries { get; set; } + public bool Scale { get; set; } [YamlMember(Alias = "scale_width_percent", ApplyNamingConventions = false)] diff --git a/ErsatzTV.Core/Interfaces/Streaming/GraphicsEngineContext.cs b/ErsatzTV.Core/Interfaces/Streaming/GraphicsEngineContext.cs index 5035fd2cf..475f74729 100644 --- a/ErsatzTV.Core/Interfaces/Streaming/GraphicsEngineContext.cs +++ b/ErsatzTV.Core/Interfaces/Streaming/GraphicsEngineContext.cs @@ -28,7 +28,10 @@ public record TextElementDataContext(TextGraphicsElement TextElement) : Graphics public int EpgEntries => TextElement.EpgEntries; } -public record ImageElementContext(ImageGraphicsElement ImageElement) : GraphicsElementContext; +public record ImageElementDataContext(ImageGraphicsElement ImageElement) : GraphicsElementContext, ITemplateDataContext +{ + public int EpgEntries => ImageElement.EpgEntries; +} public record MotionElementDataContext(MotionGraphicsElement MotionElement) : GraphicsElementContext, ITemplateDataContext diff --git a/ErsatzTV.Infrastructure/Streaming/Graphics/GraphicsElementLoader.cs b/ErsatzTV.Infrastructure/Streaming/Graphics/GraphicsElementLoader.cs index 19b2e4871..ff0715a9e 100644 --- a/ErsatzTV.Infrastructure/Streaming/Graphics/GraphicsElementLoader.cs +++ b/ErsatzTV.Infrastructure/Streaming/Graphics/GraphicsElementLoader.cs @@ -76,7 +76,10 @@ public partial class GraphicsElementLoader( reference.GraphicsElement.Path); } - context.Elements.AddRange(maybeElement.Select(element => new ImageElementContext(element))); + foreach (ImageGraphicsElement element in maybeElement) + { + context.Elements.Add(new ImageElementDataContext(element)); + } break; } @@ -203,19 +206,29 @@ public partial class GraphicsElementLoader( IEnumerable elementsWithEpg = elements.Where(e => e.GraphicsElement.Kind is GraphicsElementKind.Text or GraphicsElementKind.Subtitle - or GraphicsElementKind.Motion or GraphicsElementKind.Script); + or GraphicsElementKind.Motion or GraphicsElementKind.Script or GraphicsElementKind.Image); foreach (var reference in elementsWithEpg) { - foreach (string line in await fileSystem.File.ReadAllLinesAsync(reference.GraphicsElement.Path)) + try { - Match match = EpgEntriesRegex().Match(line); - if (!match.Success || !int.TryParse(match.Groups[1].Value, out int value)) + foreach (string line in await fileSystem.File.ReadAllLinesAsync(reference.GraphicsElement.Path)) { - continue; - } + Match match = EpgEntriesRegex().Match(line); + if (!match.Success || !int.TryParse(match.Groups[1].Value, out int value)) + { + continue; + } - epgEntries = Math.Max(epgEntries, value); + epgEntries = Math.Max(epgEntries, value); + } + } + catch (Exception ex) + { + logger.LogWarning( + ex, + "Failed to read graphics element at {Path} for EPG entries", + reference.GraphicsElement.Path); } } diff --git a/ErsatzTV.Infrastructure/Streaming/Graphics/GraphicsEngine.cs b/ErsatzTV.Infrastructure/Streaming/Graphics/GraphicsEngine.cs index 3c4198b8d..9e8dc9bcb 100644 --- a/ErsatzTV.Infrastructure/Streaming/Graphics/GraphicsEngine.cs +++ b/ErsatzTV.Infrastructure/Streaming/Graphics/GraphicsEngine.cs @@ -45,7 +45,7 @@ public class GraphicsEngine( break; - case ImageElementContext imageElementContext: + case ImageElementDataContext imageElementContext: elements.Add(new ImageElement(imageElementContext.ImageElement, logger)); break;