diff --git a/ErsatzTV.Application/Channels/Commands/RefreshChannelDataHandler.cs b/ErsatzTV.Application/Channels/Commands/RefreshChannelDataHandler.cs index 934e98d2..8c81de19 100644 --- a/ErsatzTV.Application/Channels/Commands/RefreshChannelDataHandler.cs +++ b/ErsatzTV.Application/Channels/Commands/RefreshChannelDataHandler.cs @@ -182,6 +182,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> switch (playout.ProgramSchedulePlayoutType) { case ProgramSchedulePlayoutType.Flood: + case ProgramSchedulePlayoutType.Yaml: var floodSorted = playouts .Collect(p => p.Items) .OrderBy(pi => pi.Start) diff --git a/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutBuilder.cs b/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutBuilder.cs index 1b76af31..06080f40 100644 --- a/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutBuilder.cs +++ b/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutBuilder.cs @@ -44,6 +44,7 @@ public class YamlPlayoutBuilder( System.Collections.Generic.HashSet<string> missingContentKeys = []; int itemsAfterRepeat = playout.Items.Count; + int guideGroup = 1; var index = 0; while (currentTime < finish) { @@ -60,7 +61,8 @@ public class YamlPlayoutBuilder( { case YamlPlayoutWaitUntilInstruction waitUntil: currentTime = HandleWaitUntil(currentTime, waitUntil); - break; + index++; + continue; case YamlPlayoutRepeatInstruction: // repeat resets index into YAML playout index = 0; @@ -72,6 +74,10 @@ public class YamlPlayoutBuilder( itemsAfterRepeat = playout.Items.Count; continue; + case YamlPlayoutNewEpgGroupInstruction: + guideGroup *= -1; + index++; + continue; } Option<IMediaCollectionEnumerator> maybeEnumerator = await GetCachedEnumeratorForContent( @@ -96,7 +102,7 @@ public class YamlPlayoutBuilder( switch (playoutItem) { case YamlPlayoutCountInstruction count: - currentTime = YamlPlayoutSchedulerCount.Schedule(playout, currentTime, count, enumerator); + currentTime = YamlPlayoutSchedulerCount.Schedule(playout, currentTime, guideGroup, count, enumerator); break; case YamlPlayoutDurationInstruction duration: Option<IMediaCollectionEnumerator> durationFallbackEnumerator = await GetCachedEnumeratorForContent( @@ -109,6 +115,7 @@ public class YamlPlayoutBuilder( currentTime = YamlPlayoutSchedulerDuration.Schedule( playout, currentTime, + guideGroup, duration, enumerator, durationFallbackEnumerator); @@ -124,6 +131,7 @@ public class YamlPlayoutBuilder( currentTime = YamlPlayoutSchedulerPadToNext.Schedule( playout, currentTime, + guideGroup, padToNext, enumerator, fallbackEnumerator); @@ -307,6 +315,7 @@ public class YamlPlayoutBuilder( { { "count", typeof(YamlPlayoutCountInstruction) }, { "duration", typeof(YamlPlayoutDurationInstruction) }, + { "new_epg_group", typeof(YamlPlayoutNewEpgGroupInstruction) }, { "pad_to_next", typeof(YamlPlayoutPadToNextInstruction) }, { "repeat", typeof(YamlPlayoutRepeatInstruction) }, { "skip_items", typeof(YamlPlayoutSkipItemsInstruction) }, diff --git a/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutInstruction.cs b/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutInstruction.cs index e9ee07aa..89ac5d30 100644 --- a/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutInstruction.cs +++ b/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutInstruction.cs @@ -1,6 +1,11 @@ +using YamlDotNet.Serialization; + namespace ErsatzTV.Core.Scheduling.YamlScheduling; public class YamlPlayoutInstruction { public string Content { get; set; } + + [YamlMember(Alias = "filler_kind", ApplyNamingConventions = false)] + public string FillerKind { get; set; } } diff --git a/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutNewEpgGroupInstruction.cs b/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutNewEpgGroupInstruction.cs new file mode 100644 index 00000000..3e10492e --- /dev/null +++ b/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutNewEpgGroupInstruction.cs @@ -0,0 +1,9 @@ +using YamlDotNet.Serialization; + +namespace ErsatzTV.Core.Scheduling.YamlScheduling; + +public class YamlPlayoutNewEpgGroupInstruction : YamlPlayoutInstruction +{ + [YamlMember(Alias = "new_epg_group", ApplyNamingConventions = false)] + public string NewEpgGroup { get; set; } +} diff --git a/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutScheduler.cs b/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutScheduler.cs index a08023bc..8e8a13a3 100644 --- a/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutScheduler.cs +++ b/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutScheduler.cs @@ -1,4 +1,5 @@ using ErsatzTV.Core.Domain; +using ErsatzTV.Core.Domain.Filler; using ErsatzTV.Core.Extensions; namespace ErsatzTV.Core.Scheduling.YamlScheduling; @@ -15,4 +16,16 @@ public abstract class YamlPlayoutScheduler MediaVersion version = mediaItem.GetHeadVersion(); return version.Duration; } + + protected static FillerKind GetFillerKind(YamlPlayoutInstruction instruction) + { + if (string.IsNullOrWhiteSpace(instruction.FillerKind)) + { + return FillerKind.None; + } + + return Enum.TryParse(instruction.FillerKind, ignoreCase: true, out FillerKind result) + ? result + : FillerKind.None; + } } diff --git a/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutSchedulerCount.cs b/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutSchedulerCount.cs index 8092e049..d77c9f99 100644 --- a/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutSchedulerCount.cs +++ b/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutSchedulerCount.cs @@ -1,5 +1,4 @@ using ErsatzTV.Core.Domain; -using ErsatzTV.Core.Domain.Filler; using ErsatzTV.Core.Interfaces.Scheduling; namespace ErsatzTV.Core.Scheduling.YamlScheduling; @@ -9,6 +8,7 @@ public class YamlPlayoutSchedulerCount : YamlPlayoutScheduler public static DateTimeOffset Schedule( Playout playout, DateTimeOffset currentTime, + int guideGroup, YamlPlayoutCountInstruction count, IMediaCollectionEnumerator enumerator) { @@ -26,14 +26,14 @@ public class YamlPlayoutSchedulerCount : YamlPlayoutScheduler Finish = currentTime.UtcDateTime + itemDuration, InPoint = TimeSpan.Zero, OutPoint = itemDuration, - FillerKind = FillerKind.None, //blockItem.IncludeInProgramGuide ? FillerKind.None : FillerKind.GuideMode, + FillerKind = GetFillerKind(count), //CustomTitle = scheduleItem.CustomTitle, //WatermarkId = scheduleItem.WatermarkId, //PreferredAudioLanguageCode = scheduleItem.PreferredAudioLanguageCode, //PreferredAudioTitle = scheduleItem.PreferredAudioTitle, //PreferredSubtitleLanguageCode = scheduleItem.PreferredSubtitleLanguageCode, //SubtitleMode = scheduleItem.SubtitleMode - //GuideGroup = effectiveBlock.TemplateItemId, + GuideGroup = guideGroup //GuideStart = effectiveBlock.Start.UtcDateTime, //GuideFinish = blockFinish.UtcDateTime, //BlockKey = JsonConvert.SerializeObject(effectiveBlock.BlockKey), diff --git a/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutSchedulerDuration.cs b/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutSchedulerDuration.cs index f515e424..ae59ac32 100644 --- a/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutSchedulerDuration.cs +++ b/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutSchedulerDuration.cs @@ -10,6 +10,7 @@ public class YamlPlayoutSchedulerDuration : YamlPlayoutScheduler public static DateTimeOffset Schedule( Playout playout, DateTimeOffset currentTime, + int guideGroup, YamlPlayoutDurationInstruction duration, IMediaCollectionEnumerator enumerator, Option<IMediaCollectionEnumerator> fallbackEnumerator) @@ -28,6 +29,8 @@ public class YamlPlayoutSchedulerDuration : YamlPlayoutScheduler targetTime, duration.DiscardAttempts, duration.Trim, + GetFillerKind(duration), + guideGroup, enumerator, fallbackEnumerator); } @@ -38,6 +41,8 @@ public class YamlPlayoutSchedulerDuration : YamlPlayoutScheduler DateTimeOffset targetTime, int discardAttempts, bool trim, + FillerKind fillerKind, + int guideGroup, IMediaCollectionEnumerator enumerator, Option<IMediaCollectionEnumerator> fallbackEnumerator) { @@ -56,8 +61,8 @@ public class YamlPlayoutSchedulerDuration : YamlPlayoutScheduler Finish = currentTime.UtcDateTime + itemDuration, InPoint = TimeSpan.Zero, OutPoint = itemDuration, - //GuideGroup = playoutBuilderState.NextGuideGroup, - //FillerKind = fillerKind, + GuideGroup = guideGroup, + FillerKind = fillerKind //DisableWatermarks = !allowWatermarks }; diff --git a/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutSchedulerPadToNext.cs b/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutSchedulerPadToNext.cs index b7f4bc78..770cfba8 100644 --- a/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutSchedulerPadToNext.cs +++ b/ErsatzTV.Core/Scheduling/YamlScheduling/YamlPlayoutSchedulerPadToNext.cs @@ -8,6 +8,7 @@ public class YamlPlayoutSchedulerPadToNext : YamlPlayoutSchedulerDuration public static DateTimeOffset Schedule( Playout playout, DateTimeOffset currentTime, + int guideGroup, YamlPlayoutPadToNextInstruction padToNext, IMediaCollectionEnumerator enumerator, Option<IMediaCollectionEnumerator> fallbackEnumerator) @@ -38,6 +39,8 @@ public class YamlPlayoutSchedulerPadToNext : YamlPlayoutSchedulerDuration targetTime, padToNext.DiscardAttempts, padToNext.Trim, + GetFillerKind(padToNext), + guideGroup, enumerator, fallbackEnumerator); }