Browse Source

fix: schedule all required fallback filler in classic schedules (#2867)

pull/2868/head
Jason Dove 1 month ago committed by GitHub
parent
commit
7e38297d6e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 172
      ErsatzTV.Core.Tests/Scheduling/PlayoutModeSchedulerBaseTests.cs
  2. 16
      ErsatzTV.Core.Tests/Scheduling/PlayoutModeSchedulerDurationTests.cs
  3. 24
      ErsatzTV.Core.Tests/Scheduling/PlayoutModeSchedulerFloodTests.cs
  4. 24
      ErsatzTV.Core.Tests/Scheduling/PlayoutModeSchedulerMultipleTests.cs
  5. 21
      ErsatzTV.Core.Tests/Scheduling/PlayoutModeSchedulerOneTests.cs
  6. 62
      ErsatzTV.Core/Scheduling/PlayoutModeSchedulerBase.cs

172
ErsatzTV.Core.Tests/Scheduling/PlayoutModeSchedulerBaseTests.cs

@ -731,6 +731,163 @@ public class PlayoutModeSchedulerBaseTests : SchedulerTestBase @@ -731,6 +731,163 @@ public class PlayoutModeSchedulerBaseTests : SchedulerTestBase
playoutItems[4].MediaItemId.ShouldBe(6);
playoutItems[4].StartOffset.ShouldBe(startState.CurrentTime + TimeSpan.FromMinutes(55));
}
[Test]
public void Should_Schedule_Multiple_Fallback_Items_For_Pad_Gap()
{
// content 45 min, post roll pad to 60 with an empty collection, remaining 15 min filled by 2 min fallback items
// fallback has 2 min items, so 8 items will be scheduled.
Collection collectionOne = TwoItemCollection(1, 2, TimeSpan.FromMinutes(45));
Collection collectionTwo = new Collection { Id = 2, MediaItems = new List<MediaItem>() };
Collection collectionThree = TwoItemCollection(5, 6, TimeSpan.FromMinutes(2));
var scheduleItem = new ProgramScheduleItemOne
{
Id = 1,
Index = 1,
Collection = collectionOne,
CollectionId = collectionOne.Id,
StartTime = null,
PlaybackOrder = PlaybackOrder.Chronological,
TailFiller = null,
FallbackFiller = new FillerPreset
{
FillerKind = FillerKind.Fallback,
CollectionId = 3,
Collection = collectionThree
},
PostRollFiller = new FillerPreset
{
FillerKind = FillerKind.PostRoll,
FillerMode = FillerMode.Pad,
PadToNearestMinute = 60,
CollectionId = 2,
Collection = collectionTwo
}
};
var scheduleItemsEnumerator = new OrderedScheduleItemsEnumerator(
new List<ProgramScheduleItem> { scheduleItem },
new CollectionEnumeratorState());
var enumerator = new ChronologicalMediaCollectionEnumerator(
collectionOne.MediaItems,
new CollectionEnumeratorState());
var postRollFillerEnumerator = new ChronologicalMediaCollectionEnumerator(
collectionTwo.MediaItems,
new CollectionEnumeratorState());
var fallbackFillerEnumerator = new ChronologicalMediaCollectionEnumerator(
collectionThree.MediaItems,
new CollectionEnumeratorState());
PlayoutBuilderState startState = StartState(scheduleItemsEnumerator);
Dictionary<CollectionKey, IMediaCollectionEnumerator> enumerators = CollectionEnumerators(
scheduleItem,
enumerator);
enumerators.Add(CollectionKey.ForFillerPreset(scheduleItem.PostRollFiller), postRollFillerEnumerator);
enumerators.Add(CollectionKey.ForFillerPreset(scheduleItem.FallbackFiller), fallbackFillerEnumerator);
List<PlayoutItem> playoutItems = _scheduler
.AddFiller(
startState,
enumerators,
scheduleItem,
new PlayoutItem
{
MediaItemId = 1,
Start = startState.CurrentTime.UtcDateTime,
Finish = startState.CurrentTime.AddMinutes(45).UtcDateTime
},
new List<MediaChapter>(),
new PlayoutBuildWarnings(),
_cancellationToken);
playoutItems.Count.ShouldBe(9); // 1 primary + 8 fallback
// primary
playoutItems[0].MediaItemId.ShouldBe(1);
playoutItems[0].StartOffset.ShouldBe(startState.CurrentTime);
// fallback 1
playoutItems[1].MediaItemId.ShouldBe(5);
playoutItems[1].StartOffset.ShouldBe(startState.CurrentTime + TimeSpan.FromMinutes(45));
// fallback 8 (cut short)
playoutItems[8].MediaItemId.ShouldBe(6);
playoutItems[8].StartOffset.ShouldBe(startState.CurrentTime + TimeSpan.FromMinutes(59));
(playoutItems[8].Finish - playoutItems[8].Start).ShouldBe(TimeSpan.FromMinutes(1));
playoutItems[8].OutPoint.ShouldBe(TimeSpan.FromMinutes(1));
}
}
[TestFixture]
public class AddFallback : PlayoutModeSchedulerBaseTests
{
[Test]
public void Should_Schedule_Multiple_Fallback_Items_For_Large_Gap()
{
Collection collectionOne = TwoItemCollection(1, 2, TimeSpan.FromMinutes(2));
var scheduleItem = new ProgramScheduleItemOne
{
Id = 1,
Index = 1,
FallbackFiller = new FillerPreset
{
FillerKind = FillerKind.Fallback,
CollectionId = 1,
Collection = collectionOne
}
};
var scheduleItemsEnumerator = new OrderedScheduleItemsEnumerator(
new List<ProgramScheduleItem> { scheduleItem },
new CollectionEnumeratorState());
var enumerator = new ChronologicalMediaCollectionEnumerator(
collectionOne.MediaItems,
new CollectionEnumeratorState());
PlayoutBuilderState startState = StartState(scheduleItemsEnumerator);
Dictionary<CollectionKey, IMediaCollectionEnumerator> enumerators = CollectionEnumerators(
scheduleItem,
enumerator);
enumerators.Add(CollectionKey.ForFillerPreset(scheduleItem.FallbackFiller), enumerator);
DateTimeOffset nextItemStart = startState.CurrentTime.AddMinutes(5);
Tuple<PlayoutBuilderState, List<PlayoutItem>> result = ((TestScheduler)_scheduler).TestAddFallbackFiller(
startState,
enumerators,
scheduleItem,
new List<PlayoutItem>(),
nextItemStart,
_cancellationToken);
List<PlayoutItem> playoutItems = result.Item2;
playoutItems.Count.ShouldBe(3);
playoutItems[0].MediaItemId.ShouldBe(1);
playoutItems[0].StartOffset.ShouldBe(startState.CurrentTime);
(playoutItems[0].Finish - playoutItems[0].Start).ShouldBe(TimeSpan.FromMinutes(2));
playoutItems[1].MediaItemId.ShouldBe(2);
playoutItems[1].StartOffset.ShouldBe(startState.CurrentTime.AddMinutes(2));
(playoutItems[1].Finish - playoutItems[1].Start).ShouldBe(TimeSpan.FromMinutes(2));
playoutItems[2].MediaItemId.ShouldBe(1);
playoutItems[2].StartOffset.ShouldBe(startState.CurrentTime.AddMinutes(4));
(playoutItems[2].Finish - playoutItems[2].Start).ShouldBe(TimeSpan.FromMinutes(1));
playoutItems[2].OutPoint.ShouldBe(TimeSpan.FromMinutes(1));
}
}
[TestFixture]
@ -800,6 +957,21 @@ public class PlayoutModeSchedulerBaseTests : SchedulerTestBase @@ -800,6 +957,21 @@ public class PlayoutModeSchedulerBaseTests : SchedulerTestBase
CancellationToken cancellationToken) =>
throw new NotSupportedException();
public Tuple<PlayoutBuilderState, List<PlayoutItem>> TestAddFallbackFiller(
PlayoutBuilderState playoutBuilderState,
Dictionary<CollectionKey, IMediaCollectionEnumerator> collectionEnumerators,
ProgramScheduleItem scheduleItem,
List<PlayoutItem> playoutItems,
DateTimeOffset nextItemStart,
CancellationToken cancellationToken) =>
AddFallbackFiller(
playoutBuilderState,
collectionEnumerators,
scheduleItem,
playoutItems,
nextItemStart,
cancellationToken);
protected override string SchedulingContextName => "Test";
}
}

16
ErsatzTV.Core.Tests/Scheduling/PlayoutModeSchedulerDurationTests.cs

@ -388,7 +388,7 @@ public class PlayoutModeSchedulerDurationTests : SchedulerTestBase @@ -388,7 +388,7 @@ public class PlayoutModeSchedulerDurationTests : SchedulerTestBase
enumerator1.State.Index.ShouldBe(1);
enumerator2.State.Index.ShouldBe(1);
playoutItems.Count.ShouldBe(4);
playoutItems.Count.ShouldBe(18);
playoutItems[0].MediaItemId.ShouldBe(1);
playoutItems[0].StartOffset.ShouldBe(startState.CurrentTime);
@ -413,6 +413,12 @@ public class PlayoutModeSchedulerDurationTests : SchedulerTestBase @@ -413,6 +413,12 @@ public class PlayoutModeSchedulerDurationTests : SchedulerTestBase
playoutItems[3].GuideGroup.ShouldBe(3);
playoutItems[3].FillerKind.ShouldBe(FillerKind.Fallback);
playoutItems[3].GuideFinish.HasValue.ShouldBeFalse();
playoutItems[17].MediaItemId.ShouldBe(3);
playoutItems[17].StartOffset.ShouldBe(startState.CurrentTime.Add(new TimeSpan(2, 59, 0)));
playoutItems[17].GuideGroup.ShouldBe(3);
playoutItems[17].FillerKind.ShouldBe(FillerKind.Fallback);
playoutItems[17].GuideFinish.HasValue.ShouldBeFalse();
}
[Test]
@ -694,7 +700,7 @@ public class PlayoutModeSchedulerDurationTests : SchedulerTestBase @@ -694,7 +700,7 @@ public class PlayoutModeSchedulerDurationTests : SchedulerTestBase
enumerator2.State.Index.ShouldBe(1);
enumerator3.State.Index.ShouldBe(1);
playoutItems.Count.ShouldBe(7);
playoutItems.Count.ShouldBe(9);
playoutItems[0].MediaItemId.ShouldBe(1);
playoutItems[0].StartOffset.ShouldBe(startState.CurrentTime);
@ -737,6 +743,12 @@ public class PlayoutModeSchedulerDurationTests : SchedulerTestBase @@ -737,6 +743,12 @@ public class PlayoutModeSchedulerDurationTests : SchedulerTestBase
playoutItems[6].GuideGroup.ShouldBe(3);
playoutItems[6].FillerKind.ShouldBe(FillerKind.Fallback);
playoutItems[6].GuideFinish.HasValue.ShouldBeFalse();
playoutItems[8].MediaItemId.ShouldBe(5);
playoutItems[8].StartOffset.ShouldBe(startState.CurrentTime.Add(new TimeSpan(2, 59, 0)));
playoutItems[8].GuideGroup.ShouldBe(3);
playoutItems[8].FillerKind.ShouldBe(FillerKind.Fallback);
playoutItems[8].GuideFinish.HasValue.ShouldBeFalse();
}
[Test]

24
ErsatzTV.Core.Tests/Scheduling/PlayoutModeSchedulerFloodTests.cs

@ -609,7 +609,7 @@ public class PlayoutModeSchedulerFloodTests : SchedulerTestBase @@ -609,7 +609,7 @@ public class PlayoutModeSchedulerFloodTests : SchedulerTestBase
enumerator1.State.Index.ShouldBe(1);
enumerator2.State.Index.ShouldBe(1);
playoutItems.Count.ShouldBe(4);
playoutItems.Count.ShouldBe(6);
playoutItems[0].MediaItemId.ShouldBe(1);
playoutItems[0].StartOffset.ShouldBe(startState.CurrentTime);
@ -630,6 +630,16 @@ public class PlayoutModeSchedulerFloodTests : SchedulerTestBase @@ -630,6 +630,16 @@ public class PlayoutModeSchedulerFloodTests : SchedulerTestBase
playoutItems[3].StartOffset.ShouldBe(startState.CurrentTime.Add(new TimeSpan(2, 45, 0)));
playoutItems[3].GuideGroup.ShouldBe(3);
playoutItems[3].FillerKind.ShouldBe(FillerKind.Fallback);
playoutItems[4].MediaItemId.ShouldBe(4);
playoutItems[4].StartOffset.ShouldBe(startState.CurrentTime.Add(new TimeSpan(2, 50, 0)));
playoutItems[4].GuideGroup.ShouldBe(3);
playoutItems[4].FillerKind.ShouldBe(FillerKind.Fallback);
playoutItems[5].MediaItemId.ShouldBe(3);
playoutItems[5].StartOffset.ShouldBe(startState.CurrentTime.Add(new TimeSpan(2, 55, 0)));
playoutItems[5].GuideGroup.ShouldBe(3);
playoutItems[5].FillerKind.ShouldBe(FillerKind.Fallback);
}
[Test]
@ -814,7 +824,7 @@ public class PlayoutModeSchedulerFloodTests : SchedulerTestBase @@ -814,7 +824,7 @@ public class PlayoutModeSchedulerFloodTests : SchedulerTestBase
enumerator2.State.Index.ShouldBe(1);
enumerator3.State.Index.ShouldBe(1);
playoutItems.Count.ShouldBe(7);
playoutItems.Count.ShouldBe(9);
playoutItems[0].MediaItemId.ShouldBe(1);
playoutItems[0].StartOffset.ShouldBe(startState.CurrentTime);
@ -850,6 +860,16 @@ public class PlayoutModeSchedulerFloodTests : SchedulerTestBase @@ -850,6 +860,16 @@ public class PlayoutModeSchedulerFloodTests : SchedulerTestBase
playoutItems[6].StartOffset.ShouldBe(startState.CurrentTime.Add(new TimeSpan(2, 57, 0)));
playoutItems[6].GuideGroup.ShouldBe(3);
playoutItems[6].FillerKind.ShouldBe(FillerKind.Fallback);
playoutItems[7].MediaItemId.ShouldBe(6);
playoutItems[7].StartOffset.ShouldBe(startState.CurrentTime.Add(new TimeSpan(2, 58, 0)));
playoutItems[7].GuideGroup.ShouldBe(3);
playoutItems[7].FillerKind.ShouldBe(FillerKind.Fallback);
playoutItems[8].MediaItemId.ShouldBe(5);
playoutItems[8].StartOffset.ShouldBe(startState.CurrentTime.Add(new TimeSpan(2, 59, 0)));
playoutItems[8].GuideGroup.ShouldBe(3);
playoutItems[8].FillerKind.ShouldBe(FillerKind.Fallback);
}
[Test]

24
ErsatzTV.Core.Tests/Scheduling/PlayoutModeSchedulerMultipleTests.cs

@ -515,7 +515,7 @@ public class PlayoutModeSchedulerMultipleTests : SchedulerTestBase @@ -515,7 +515,7 @@ public class PlayoutModeSchedulerMultipleTests : SchedulerTestBase
enumerator1.State.Index.ShouldBe(1);
enumerator2.State.Index.ShouldBe(1);
playoutItems.Count.ShouldBe(4);
playoutItems.Count.ShouldBe(6);
playoutItems[0].MediaItemId.ShouldBe(1);
playoutItems[0].StartOffset.ShouldBe(startState.CurrentTime);
@ -536,6 +536,16 @@ public class PlayoutModeSchedulerMultipleTests : SchedulerTestBase @@ -536,6 +536,16 @@ public class PlayoutModeSchedulerMultipleTests : SchedulerTestBase
playoutItems[3].StartOffset.ShouldBe(startState.CurrentTime.Add(new TimeSpan(2, 45, 0)));
playoutItems[3].GuideGroup.ShouldBe(3);
playoutItems[3].FillerKind.ShouldBe(FillerKind.Fallback);
playoutItems[4].MediaItemId.ShouldBe(4);
playoutItems[4].StartOffset.ShouldBe(startState.CurrentTime.Add(new TimeSpan(2, 50, 0)));
playoutItems[4].GuideGroup.ShouldBe(3);
playoutItems[4].FillerKind.ShouldBe(FillerKind.Fallback);
playoutItems[5].MediaItemId.ShouldBe(3);
playoutItems[5].StartOffset.ShouldBe(startState.CurrentTime.Add(new TimeSpan(2, 55, 0)));
playoutItems[5].GuideGroup.ShouldBe(3);
playoutItems[5].FillerKind.ShouldBe(FillerKind.Fallback);
}
[Test]
@ -723,7 +733,7 @@ public class PlayoutModeSchedulerMultipleTests : SchedulerTestBase @@ -723,7 +733,7 @@ public class PlayoutModeSchedulerMultipleTests : SchedulerTestBase
enumerator2.State.Index.ShouldBe(1);
enumerator3.State.Index.ShouldBe(1);
playoutItems.Count.ShouldBe(7);
playoutItems.Count.ShouldBe(9);
playoutItems[0].MediaItemId.ShouldBe(1);
playoutItems[0].StartOffset.ShouldBe(startState.CurrentTime);
@ -759,6 +769,16 @@ public class PlayoutModeSchedulerMultipleTests : SchedulerTestBase @@ -759,6 +769,16 @@ public class PlayoutModeSchedulerMultipleTests : SchedulerTestBase
playoutItems[6].StartOffset.ShouldBe(startState.CurrentTime.Add(new TimeSpan(2, 57, 0)));
playoutItems[6].GuideGroup.ShouldBe(3);
playoutItems[6].FillerKind.ShouldBe(FillerKind.Fallback);
playoutItems[7].MediaItemId.ShouldBe(6);
playoutItems[7].StartOffset.ShouldBe(startState.CurrentTime.Add(new TimeSpan(2, 58, 0)));
playoutItems[7].GuideGroup.ShouldBe(3);
playoutItems[7].FillerKind.ShouldBe(FillerKind.Fallback);
playoutItems[8].MediaItemId.ShouldBe(5);
playoutItems[8].StartOffset.ShouldBe(startState.CurrentTime.Add(new TimeSpan(2, 59, 0)));
playoutItems[8].GuideGroup.ShouldBe(3);
playoutItems[8].FillerKind.ShouldBe(FillerKind.Fallback);
}
[Test]

21
ErsatzTV.Core.Tests/Scheduling/PlayoutModeSchedulerOneTests.cs

@ -306,9 +306,9 @@ public class PlayoutModeSchedulerOneTests : SchedulerTestBase @@ -306,9 +306,9 @@ public class PlayoutModeSchedulerOneTests : SchedulerTestBase
playoutBuilderState.ScheduleItemsEnumerator.State.Index.ShouldBe(0);
enumerator1.State.Index.ShouldBe(1);
enumerator2.State.Index.ShouldBe(1);
enumerator2.State.Index.ShouldBe(0);
playoutItems.Count.ShouldBe(2);
playoutItems.Count.ShouldBe(25);
playoutItems[0].MediaItemId.ShouldBe(1);
playoutItems[0].StartOffset.ShouldBe(startState.CurrentTime);
@ -319,6 +319,11 @@ public class PlayoutModeSchedulerOneTests : SchedulerTestBase @@ -319,6 +319,11 @@ public class PlayoutModeSchedulerOneTests : SchedulerTestBase
playoutItems[1].StartOffset.ShouldBe(startState.CurrentTime.AddHours(1));
playoutItems[1].GuideGroup.ShouldBe(1);
playoutItems[1].FillerKind.ShouldBe(FillerKind.Fallback);
playoutItems[24].MediaItemId.ShouldBe(4);
playoutItems[24].StartOffset.ShouldBe(startState.CurrentTime.AddHours(3).Subtract(TimeSpan.FromMinutes(5)));
playoutItems[24].GuideGroup.ShouldBe(1);
playoutItems[24].FillerKind.ShouldBe(FillerKind.Fallback);
}
[Test]
@ -481,7 +486,7 @@ public class PlayoutModeSchedulerOneTests : SchedulerTestBase @@ -481,7 +486,7 @@ public class PlayoutModeSchedulerOneTests : SchedulerTestBase
enumerator2.State.Index.ShouldBe(1);
enumerator3.State.Index.ShouldBe(1);
playoutItems.Count.ShouldBe(5);
playoutItems.Count.ShouldBe(7);
playoutItems[0].MediaItemId.ShouldBe(1);
playoutItems[0].StartOffset.ShouldBe(startState.CurrentTime);
@ -507,6 +512,16 @@ public class PlayoutModeSchedulerOneTests : SchedulerTestBase @@ -507,6 +512,16 @@ public class PlayoutModeSchedulerOneTests : SchedulerTestBase
playoutItems[4].StartOffset.ShouldBe(startState.CurrentTime.Add(new TimeSpan(2, 57, 0)));
playoutItems[4].GuideGroup.ShouldBe(1);
playoutItems[4].FillerKind.ShouldBe(FillerKind.Fallback);
playoutItems[5].MediaItemId.ShouldBe(6);
playoutItems[5].StartOffset.ShouldBe(startState.CurrentTime.Add(new TimeSpan(2, 58, 0)));
playoutItems[5].GuideGroup.ShouldBe(1);
playoutItems[5].FillerKind.ShouldBe(FillerKind.Fallback);
playoutItems[6].MediaItemId.ShouldBe(5);
playoutItems[6].StartOffset.ShouldBe(startState.CurrentTime.Add(new TimeSpan(2, 59, 0)));
playoutItems[6].GuideGroup.ShouldBe(1);
playoutItems[6].FillerKind.ShouldBe(FillerKind.Fallback);
}
[Test]

62
ErsatzTV.Core/Scheduling/PlayoutModeSchedulerBase.cs

@ -210,19 +210,27 @@ public abstract class PlayoutModeSchedulerBase<T>(ILogger logger) : IPlayoutMode @@ -210,19 +210,27 @@ public abstract class PlayoutModeSchedulerBase<T>(ILogger logger) : IPlayoutMode
IMediaCollectionEnumerator enumerator =
collectionEnumerators[CollectionKey.ForFillerPreset(scheduleItem.FallbackFiller)];
foreach (MediaItem mediaItem in enumerator.Current)
while (enumerator.Current.IsSome && nextState.CurrentTime < nextItemStart)
{
MediaItem mediaItem = enumerator.Current.ValueUnsafe();
TimeSpan itemDuration = mediaItem.GetDurationForPlayout();
TimeSpan gap = nextItemStart - nextState.CurrentTime;
TimeSpan duration = itemDuration < gap ? itemDuration : gap;
TimeSpan inPoint = InPointForMediaItem(mediaItem);
var playoutItem = new PlayoutItem
{
PlayoutId = playoutBuilderState.PlayoutId,
MediaItemId = mediaItem.Id,
MediaItemId = IdForMediaItem(mediaItem),
Start = nextState.CurrentTime.UtcDateTime,
Finish = nextItemStart.UtcDateTime,
InPoint = TimeSpan.Zero,
OutPoint = TimeSpan.Zero,
Finish = nextState.CurrentTime.Add(duration).UtcDateTime,
InPoint = inPoint,
OutPoint = inPoint + duration,
GuideGroup = nextState.NextGuideGroup,
FillerKind = FillerKind.Fallback,
DisableWatermarks = !scheduleItem.FallbackFiller.AllowWatermarks,
ChapterTitle = ChapterTitleForMediaItem(mediaItem),
SchedulingContext = GetSchedulingContext(scheduleItem, scheduleItem.FallbackFillerId, enumerator)
};
@ -230,7 +238,7 @@ public abstract class PlayoutModeSchedulerBase<T>(ILogger logger) : IPlayoutMode @@ -230,7 +238,7 @@ public abstract class PlayoutModeSchedulerBase<T>(ILogger logger) : IPlayoutMode
nextState = nextState with
{
CurrentTime = nextItemStart.UtcDateTime
CurrentTime = nextState.CurrentTime.Add(duration)
};
enumerator.MoveNext(playoutItem.StartOffset);
@ -704,14 +712,14 @@ public abstract class PlayoutModeSchedulerBase<T>(ILogger logger) : IPlayoutMode @@ -704,14 +712,14 @@ public abstract class PlayoutModeSchedulerBase<T>(ILogger logger) : IPlayoutMode
? leftOverall
: leftInThisBreak;
Option<PlayoutItem> maybeFallback = FallbackFillerForPad(
List<PlayoutItem> fallbackItems = FallbackFillerForPad(
playoutBuilderState,
enumerators,
scheduleItem,
i < filteredChapters.Count - 1 ? maxThisBreak : leftOverall,
cancellationToken);
foreach (PlayoutItem fallback in maybeFallback)
foreach (PlayoutItem fallback in fallbackItems)
{
current += fallback.Finish - fallback.Start;
filled += fallback.Finish - fallback.Start;
@ -864,41 +872,55 @@ public abstract class PlayoutModeSchedulerBase<T>(ILogger logger) : IPlayoutMode @@ -864,41 +872,55 @@ public abstract class PlayoutModeSchedulerBase<T>(ILogger logger) : IPlayoutMode
return result;
}
private static Option<PlayoutItem> FallbackFillerForPad(
private static List<PlayoutItem> FallbackFillerForPad(
PlayoutBuilderState playoutBuilderState,
Dictionary<CollectionKey, IMediaCollectionEnumerator> enumerators,
ProgramScheduleItem scheduleItem,
TimeSpan duration,
CancellationToken cancellationToken)
{
var result = new List<PlayoutItem>();
if (scheduleItem.FallbackFiller != null)
{
IMediaCollectionEnumerator enumerator =
enumerators[CollectionKey.ForFillerPreset(scheduleItem.FallbackFiller)];
foreach (MediaItem mediaItem in enumerator.Current)
TimeSpan remainingToFill = duration;
DateTimeOffset currentTime = new DateTimeOffset(2020, 2, 1, 0, 0, 0, TimeSpan.Zero);
while (enumerator.Current.IsSome && remainingToFill > TimeSpan.Zero)
{
var result = new PlayoutItem
MediaItem mediaItem = enumerator.Current.ValueUnsafe();
TimeSpan itemDuration = mediaItem.GetDurationForPlayout();
TimeSpan currentDuration = itemDuration < remainingToFill ? itemDuration : remainingToFill;
TimeSpan inPoint = InPointForMediaItem(mediaItem);
var playoutItem = new PlayoutItem
{
PlayoutId = playoutBuilderState.PlayoutId,
MediaItemId = mediaItem.Id,
Start = new DateTime(2020, 2, 1, 0, 0, 0, DateTimeKind.Utc),
Finish = new DateTime(2020, 2, 1, 0, 0, 0, DateTimeKind.Utc) + duration,
InPoint = TimeSpan.Zero,
OutPoint = TimeSpan.Zero,
MediaItemId = IdForMediaItem(mediaItem),
Start = currentTime.UtcDateTime,
Finish = currentTime.Add(currentDuration).UtcDateTime,
InPoint = inPoint,
OutPoint = inPoint + currentDuration,
GuideGroup = playoutBuilderState.NextGuideGroup,
FillerKind = FillerKind.Fallback,
DisableWatermarks = !scheduleItem.FallbackFiller.AllowWatermarks
DisableWatermarks = !scheduleItem.FallbackFiller.AllowWatermarks,
ChapterTitle = ChapterTitleForMediaItem(mediaItem)
};
result.Add(playoutItem);
remainingToFill -= currentDuration;
currentTime += currentDuration;
// TODO: this won't work with reruns
enumerator.MoveNext(Option<DateTimeOffset>.None);
return result;
}
}
return None;
return result;
}
private List<PlayoutItem> AddRandomCountFiller(

Loading…
Cancel
Save