From 2ea0e64ac196f5fa37c644cf8d88b68a1d0e46b2 Mon Sep 17 00:00:00 2001 From: Jason Dove Date: Sun, 24 Oct 2021 22:00:21 -0500 Subject: [PATCH] fix duration schedule item epg (#455) --- CHANGELOG.md | 1 + .../PlayoutModeSchedulerDurationTests.cs | 100 ++++++++++++------ .../PlayoutModeSchedulerDuration.cs | 14 ++- 3 files changed, 80 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fdb59a65f..5c5cbc719 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +- Fix EPG entries for Duration schedule items that play multiple items ## [0.2.1-alpha] - 2021-10-24 ### Fixed diff --git a/ErsatzTV.Core.Tests/Scheduling/PlayoutModeSchedulerDurationTests.cs b/ErsatzTV.Core.Tests/Scheduling/PlayoutModeSchedulerDurationTests.cs index 36797dcef..40179d8a9 100644 --- a/ErsatzTV.Core.Tests/Scheduling/PlayoutModeSchedulerDurationTests.cs +++ b/ErsatzTV.Core.Tests/Scheduling/PlayoutModeSchedulerDurationTests.cs @@ -46,7 +46,7 @@ namespace ErsatzTV.Core.Tests.Scheduling playoutBuilderState.CurrentTime.Should().Be(StartState.CurrentTime.AddHours(3)); playoutItems.Last().FinishOffset.Should().Be(playoutBuilderState.CurrentTime); - playoutBuilderState.NextGuideGroup.Should().Be(2); + playoutBuilderState.NextGuideGroup.Should().Be(4); playoutBuilderState.DurationFinish.IsNone.Should().BeTrue(); playoutBuilderState.InFlood.Should().BeFalse(); playoutBuilderState.MultipleRemaining.IsNone.Should().BeTrue(); @@ -61,16 +61,19 @@ namespace ErsatzTV.Core.Tests.Scheduling playoutItems[0].StartOffset.Should().Be(StartState.CurrentTime); playoutItems[0].GuideGroup.Should().Be(1); playoutItems[0].FillerKind.Should().Be(FillerKind.None); + playoutItems[0].GuideFinish.HasValue.Should().BeFalse(); playoutItems[1].MediaItemId.Should().Be(2); playoutItems[1].StartOffset.Should().Be(StartState.CurrentTime.AddHours(1)); - playoutItems[1].GuideGroup.Should().Be(1); + playoutItems[1].GuideGroup.Should().Be(2); playoutItems[1].FillerKind.Should().Be(FillerKind.None); + playoutItems[1].GuideFinish.HasValue.Should().BeFalse(); playoutItems[2].MediaItemId.Should().Be(1); playoutItems[2].StartOffset.Should().Be(StartState.CurrentTime.AddHours(2)); - playoutItems[2].GuideGroup.Should().Be(1); + playoutItems[2].GuideGroup.Should().Be(3); playoutItems[2].FillerKind.Should().Be(FillerKind.None); + playoutItems[2].GuideFinish.HasValue.Should().BeTrue(); } [Test] @@ -105,7 +108,7 @@ namespace ErsatzTV.Core.Tests.Scheduling playoutBuilderState.CurrentTime.Should().Be(StartState.CurrentTime.Add(new TimeSpan(2, 45, 0))); playoutItems.Last().FinishOffset.Should().Be(playoutBuilderState.CurrentTime); - playoutBuilderState.NextGuideGroup.Should().Be(2); + playoutBuilderState.NextGuideGroup.Should().Be(4); playoutBuilderState.DurationFinish.IsNone.Should().BeTrue(); playoutBuilderState.InFlood.Should().BeFalse(); playoutBuilderState.MultipleRemaining.IsNone.Should().BeTrue(); @@ -120,16 +123,19 @@ namespace ErsatzTV.Core.Tests.Scheduling playoutItems[0].StartOffset.Should().Be(StartState.CurrentTime); playoutItems[0].GuideGroup.Should().Be(1); playoutItems[0].FillerKind.Should().Be(FillerKind.None); + playoutItems[0].GuideFinish.HasValue.Should().BeFalse(); playoutItems[1].MediaItemId.Should().Be(2); playoutItems[1].StartOffset.Should().Be(StartState.CurrentTime.AddMinutes(55)); - playoutItems[1].GuideGroup.Should().Be(1); + playoutItems[1].GuideGroup.Should().Be(2); playoutItems[1].FillerKind.Should().Be(FillerKind.None); + playoutItems[1].GuideFinish.HasValue.Should().BeFalse(); playoutItems[2].MediaItemId.Should().Be(1); playoutItems[2].StartOffset.Should().Be(StartState.CurrentTime.Add(new TimeSpan(1, 50, 0))); - playoutItems[2].GuideGroup.Should().Be(1); + playoutItems[2].GuideGroup.Should().Be(3); playoutItems[2].FillerKind.Should().Be(FillerKind.None); + playoutItems[2].GuideFinish.HasValue.Should().BeTrue(); } [Test] @@ -165,7 +171,7 @@ namespace ErsatzTV.Core.Tests.Scheduling playoutBuilderState.CurrentTime.Should().Be(StartState.CurrentTime.AddHours(3)); playoutItems.Last().FinishOffset.Should().Be(StartState.CurrentTime.Add(new TimeSpan(2, 45, 0))); - playoutBuilderState.NextGuideGroup.Should().Be(2); + playoutBuilderState.NextGuideGroup.Should().Be(4); playoutBuilderState.DurationFinish.IsNone.Should().BeTrue(); playoutBuilderState.InFlood.Should().BeFalse(); playoutBuilderState.MultipleRemaining.IsNone.Should().BeTrue(); @@ -180,16 +186,19 @@ namespace ErsatzTV.Core.Tests.Scheduling playoutItems[0].StartOffset.Should().Be(StartState.CurrentTime); playoutItems[0].GuideGroup.Should().Be(1); playoutItems[0].FillerKind.Should().Be(FillerKind.None); + playoutItems[0].GuideFinish.HasValue.Should().BeFalse(); playoutItems[1].MediaItemId.Should().Be(2); playoutItems[1].StartOffset.Should().Be(StartState.CurrentTime.AddMinutes(55)); - playoutItems[1].GuideGroup.Should().Be(1); + playoutItems[1].GuideGroup.Should().Be(2); playoutItems[1].FillerKind.Should().Be(FillerKind.None); + playoutItems[1].GuideFinish.HasValue.Should().BeFalse(); playoutItems[2].MediaItemId.Should().Be(1); playoutItems[2].StartOffset.Should().Be(StartState.CurrentTime.Add(new TimeSpan(1, 50, 0))); - playoutItems[2].GuideGroup.Should().Be(1); + playoutItems[2].GuideGroup.Should().Be(3); playoutItems[2].FillerKind.Should().Be(FillerKind.None); + playoutItems[2].GuideFinish.HasValue.Should().BeTrue(); } [Test] @@ -235,7 +244,7 @@ namespace ErsatzTV.Core.Tests.Scheduling playoutBuilderState.CurrentTime.Should().Be(StartState.CurrentTime.AddHours(3)); playoutItems.Last().FinishOffset.Should().Be(playoutBuilderState.CurrentTime); - playoutBuilderState.NextGuideGroup.Should().Be(2); + playoutBuilderState.NextGuideGroup.Should().Be(4); playoutBuilderState.DurationFinish.IsNone.Should().BeTrue(); playoutBuilderState.InFlood.Should().BeFalse(); playoutBuilderState.MultipleRemaining.IsNone.Should().BeTrue(); @@ -251,21 +260,25 @@ namespace ErsatzTV.Core.Tests.Scheduling playoutItems[0].StartOffset.Should().Be(StartState.CurrentTime); playoutItems[0].GuideGroup.Should().Be(1); playoutItems[0].FillerKind.Should().Be(FillerKind.None); + playoutItems[0].GuideFinish.HasValue.Should().BeFalse(); playoutItems[1].MediaItemId.Should().Be(2); playoutItems[1].StartOffset.Should().Be(StartState.CurrentTime.AddMinutes(55)); - playoutItems[1].GuideGroup.Should().Be(1); + playoutItems[1].GuideGroup.Should().Be(2); playoutItems[1].FillerKind.Should().Be(FillerKind.None); + playoutItems[1].GuideFinish.HasValue.Should().BeFalse(); playoutItems[2].MediaItemId.Should().Be(1); playoutItems[2].StartOffset.Should().Be(StartState.CurrentTime.Add(new TimeSpan(1, 50, 0))); - playoutItems[2].GuideGroup.Should().Be(1); + playoutItems[2].GuideGroup.Should().Be(3); playoutItems[2].FillerKind.Should().Be(FillerKind.None); + playoutItems[2].GuideFinish.HasValue.Should().BeTrue(); playoutItems[3].MediaItemId.Should().Be(3); playoutItems[3].StartOffset.Should().Be(StartState.CurrentTime.Add(new TimeSpan(2, 45, 0))); - playoutItems[3].GuideGroup.Should().Be(1); + playoutItems[3].GuideGroup.Should().Be(3); playoutItems[3].FillerKind.Should().Be(FillerKind.Fallback); + playoutItems[3].GuideFinish.HasValue.Should().BeFalse(); } [Test] @@ -311,7 +324,7 @@ namespace ErsatzTV.Core.Tests.Scheduling playoutBuilderState.CurrentTime.Should().Be(StartState.CurrentTime.AddHours(3)); playoutItems.Last().FinishOffset.Should().Be(playoutBuilderState.CurrentTime); - playoutBuilderState.NextGuideGroup.Should().Be(2); + playoutBuilderState.NextGuideGroup.Should().Be(4); playoutBuilderState.DurationFinish.IsNone.Should().BeTrue(); playoutBuilderState.InFlood.Should().BeFalse(); playoutBuilderState.MultipleRemaining.IsNone.Should().BeTrue(); @@ -327,31 +340,37 @@ namespace ErsatzTV.Core.Tests.Scheduling playoutItems[0].StartOffset.Should().Be(StartState.CurrentTime); playoutItems[0].GuideGroup.Should().Be(1); playoutItems[0].FillerKind.Should().Be(FillerKind.None); + playoutItems[0].GuideFinish.HasValue.Should().BeFalse(); playoutItems[1].MediaItemId.Should().Be(2); playoutItems[1].StartOffset.Should().Be(StartState.CurrentTime.AddMinutes(55)); - playoutItems[1].GuideGroup.Should().Be(1); + playoutItems[1].GuideGroup.Should().Be(2); playoutItems[1].FillerKind.Should().Be(FillerKind.None); + playoutItems[1].GuideFinish.HasValue.Should().BeFalse(); playoutItems[2].MediaItemId.Should().Be(1); playoutItems[2].StartOffset.Should().Be(StartState.CurrentTime.Add(new TimeSpan(1, 50, 0))); - playoutItems[2].GuideGroup.Should().Be(1); + playoutItems[2].GuideGroup.Should().Be(3); playoutItems[2].FillerKind.Should().Be(FillerKind.None); + playoutItems[2].GuideFinish.HasValue.Should().BeTrue(); playoutItems[3].MediaItemId.Should().Be(3); playoutItems[3].StartOffset.Should().Be(StartState.CurrentTime.Add(new TimeSpan(2, 45, 0))); - playoutItems[3].GuideGroup.Should().Be(1); + playoutItems[3].GuideGroup.Should().Be(3); playoutItems[3].FillerKind.Should().Be(FillerKind.Tail); + playoutItems[3].GuideFinish.HasValue.Should().BeFalse(); playoutItems[4].MediaItemId.Should().Be(4); playoutItems[4].StartOffset.Should().Be(StartState.CurrentTime.Add(new TimeSpan(2, 50, 0))); - playoutItems[4].GuideGroup.Should().Be(1); + playoutItems[4].GuideGroup.Should().Be(3); playoutItems[4].FillerKind.Should().Be(FillerKind.Tail); + playoutItems[3].GuideFinish.HasValue.Should().BeFalse(); playoutItems[5].MediaItemId.Should().Be(3); playoutItems[5].StartOffset.Should().Be(StartState.CurrentTime.Add(new TimeSpan(2, 55, 0))); - playoutItems[5].GuideGroup.Should().Be(1); + playoutItems[5].GuideGroup.Should().Be(3); playoutItems[5].FillerKind.Should().Be(FillerKind.Tail); + playoutItems[3].GuideFinish.HasValue.Should().BeFalse(); } [Test] @@ -397,7 +416,7 @@ namespace ErsatzTV.Core.Tests.Scheduling playoutBuilderState.CurrentTime.Should().Be(StartState.CurrentTime.AddHours(3)); playoutItems.Last().FinishOffset.Should().Be(StartState.CurrentTime.Add(new TimeSpan(2, 57, 0))); - playoutBuilderState.NextGuideGroup.Should().Be(2); + playoutBuilderState.NextGuideGroup.Should().Be(4); playoutBuilderState.DurationFinish.IsNone.Should().BeTrue(); playoutBuilderState.InFlood.Should().BeFalse(); playoutBuilderState.MultipleRemaining.IsNone.Should().BeTrue(); @@ -413,31 +432,37 @@ namespace ErsatzTV.Core.Tests.Scheduling playoutItems[0].StartOffset.Should().Be(StartState.CurrentTime); playoutItems[0].GuideGroup.Should().Be(1); playoutItems[0].FillerKind.Should().Be(FillerKind.None); + playoutItems[0].GuideFinish.HasValue.Should().BeFalse(); playoutItems[1].MediaItemId.Should().Be(2); playoutItems[1].StartOffset.Should().Be(StartState.CurrentTime.AddMinutes(55)); - playoutItems[1].GuideGroup.Should().Be(1); + playoutItems[1].GuideGroup.Should().Be(2); playoutItems[1].FillerKind.Should().Be(FillerKind.None); + playoutItems[1].GuideFinish.HasValue.Should().BeFalse(); playoutItems[2].MediaItemId.Should().Be(1); playoutItems[2].StartOffset.Should().Be(StartState.CurrentTime.Add(new TimeSpan(1, 50, 0))); - playoutItems[2].GuideGroup.Should().Be(1); + playoutItems[2].GuideGroup.Should().Be(3); playoutItems[2].FillerKind.Should().Be(FillerKind.None); + playoutItems[2].GuideFinish.HasValue.Should().BeTrue(); playoutItems[3].MediaItemId.Should().Be(3); playoutItems[3].StartOffset.Should().Be(StartState.CurrentTime.Add(new TimeSpan(2, 45, 0))); - playoutItems[3].GuideGroup.Should().Be(1); + playoutItems[3].GuideGroup.Should().Be(3); playoutItems[3].FillerKind.Should().Be(FillerKind.Tail); + playoutItems[3].GuideFinish.HasValue.Should().BeFalse(); playoutItems[4].MediaItemId.Should().Be(4); playoutItems[4].StartOffset.Should().Be(StartState.CurrentTime.Add(new TimeSpan(2, 49, 0))); - playoutItems[4].GuideGroup.Should().Be(1); + playoutItems[4].GuideGroup.Should().Be(3); playoutItems[4].FillerKind.Should().Be(FillerKind.Tail); + playoutItems[4].GuideFinish.HasValue.Should().BeFalse(); playoutItems[5].MediaItemId.Should().Be(3); playoutItems[5].StartOffset.Should().Be(StartState.CurrentTime.Add(new TimeSpan(2, 53, 0))); - playoutItems[5].GuideGroup.Should().Be(1); + playoutItems[5].GuideGroup.Should().Be(3); playoutItems[5].FillerKind.Should().Be(FillerKind.Tail); + playoutItems[5].GuideFinish.HasValue.Should().BeFalse(); } [Test] @@ -500,7 +525,7 @@ namespace ErsatzTV.Core.Tests.Scheduling playoutBuilderState.CurrentTime.Should().Be(StartState.CurrentTime.AddHours(3)); playoutItems.Last().FinishOffset.Should().Be(playoutBuilderState.CurrentTime); - playoutBuilderState.NextGuideGroup.Should().Be(2); + playoutBuilderState.NextGuideGroup.Should().Be(4); playoutBuilderState.DurationFinish.IsNone.Should().BeTrue(); playoutBuilderState.InFlood.Should().BeFalse(); playoutBuilderState.MultipleRemaining.IsNone.Should().BeTrue(); @@ -517,36 +542,43 @@ namespace ErsatzTV.Core.Tests.Scheduling playoutItems[0].StartOffset.Should().Be(StartState.CurrentTime); playoutItems[0].GuideGroup.Should().Be(1); playoutItems[0].FillerKind.Should().Be(FillerKind.None); + playoutItems[0].GuideFinish.HasValue.Should().BeFalse(); playoutItems[1].MediaItemId.Should().Be(2); playoutItems[1].StartOffset.Should().Be(StartState.CurrentTime.AddMinutes(55)); - playoutItems[1].GuideGroup.Should().Be(1); + playoutItems[1].GuideGroup.Should().Be(2); playoutItems[1].FillerKind.Should().Be(FillerKind.None); - + playoutItems[1].GuideFinish.HasValue.Should().BeFalse(); + playoutItems[2].MediaItemId.Should().Be(1); playoutItems[2].StartOffset.Should().Be(StartState.CurrentTime.Add(new TimeSpan(1, 50, 0))); - playoutItems[2].GuideGroup.Should().Be(1); + playoutItems[2].GuideGroup.Should().Be(3); playoutItems[2].FillerKind.Should().Be(FillerKind.None); - + playoutItems[2].GuideFinish.HasValue.Should().BeTrue(); + playoutItems[3].MediaItemId.Should().Be(3); playoutItems[3].StartOffset.Should().Be(StartState.CurrentTime.Add(new TimeSpan(2, 45, 0))); - playoutItems[3].GuideGroup.Should().Be(1); + playoutItems[3].GuideGroup.Should().Be(3); playoutItems[3].FillerKind.Should().Be(FillerKind.Tail); + playoutItems[3].GuideFinish.HasValue.Should().BeFalse(); playoutItems[4].MediaItemId.Should().Be(4); playoutItems[4].StartOffset.Should().Be(StartState.CurrentTime.Add(new TimeSpan(2, 49, 0))); - playoutItems[4].GuideGroup.Should().Be(1); + playoutItems[4].GuideGroup.Should().Be(3); playoutItems[4].FillerKind.Should().Be(FillerKind.Tail); + playoutItems[4].GuideFinish.HasValue.Should().BeFalse(); playoutItems[5].MediaItemId.Should().Be(3); playoutItems[5].StartOffset.Should().Be(StartState.CurrentTime.Add(new TimeSpan(2, 53, 0))); - playoutItems[5].GuideGroup.Should().Be(1); + playoutItems[5].GuideGroup.Should().Be(3); playoutItems[5].FillerKind.Should().Be(FillerKind.Tail); + playoutItems[5].GuideFinish.HasValue.Should().BeFalse(); playoutItems[6].MediaItemId.Should().Be(5); playoutItems[6].StartOffset.Should().Be(StartState.CurrentTime.Add(new TimeSpan(2, 57, 0))); - playoutItems[6].GuideGroup.Should().Be(1); + playoutItems[6].GuideGroup.Should().Be(3); playoutItems[6].FillerKind.Should().Be(FillerKind.Fallback); + playoutItems[6].GuideFinish.HasValue.Should().BeFalse(); } } } diff --git a/ErsatzTV.Core/Scheduling/PlayoutModeSchedulerDuration.cs b/ErsatzTV.Core/Scheduling/PlayoutModeSchedulerDuration.cs index 784e414fa..2264ee84a 100644 --- a/ErsatzTV.Core/Scheduling/PlayoutModeSchedulerDuration.cs +++ b/ErsatzTV.Core/Scheduling/PlayoutModeSchedulerDuration.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain.Filler; using ErsatzTV.Core.Interfaces.Scheduling; @@ -97,7 +98,8 @@ namespace ErsatzTV.Core.Scheduling nextState = nextState with { - CurrentTime = itemEndTimeWithFiller + CurrentTime = itemEndTimeWithFiller, + NextGuideGroup = nextState.IncrementGuideGroup }; contentEnumerator.MoveNext(); @@ -131,6 +133,8 @@ namespace ErsatzTV.Core.Scheduling }; } + nextState = nextState with { NextGuideGroup = nextState.DecrementGuideGroup }; + foreach (DateTimeOffset nextItemStart in durationUntil) { switch (scheduleItem.TailMode) @@ -174,6 +178,14 @@ namespace ErsatzTV.Core.Scheduling } } + // clear guide finish on all but the last item + var all = playoutItems.Filter(pi => pi.FillerKind == FillerKind.None).ToList(); + PlayoutItem last = all.OrderBy(pi => pi.FinishOffset).LastOrDefault(); + foreach (PlayoutItem item in all.Filter(pi => pi != last)) + { + item.GuideFinish = null; + } + nextState = nextState with { NextGuideGroup = nextState.IncrementGuideGroup }; return Tuple(nextState, playoutItems);