diff --git a/ErsatzTV.Core/Scheduling/BlockScheduling/BlockPlayoutShuffledMediaCollectionEnumerator.cs b/ErsatzTV.Core/Scheduling/BlockScheduling/BlockPlayoutShuffledMediaCollectionEnumerator.cs index 83854da3..963bddc2 100644 --- a/ErsatzTV.Core/Scheduling/BlockScheduling/BlockPlayoutShuffledMediaCollectionEnumerator.cs +++ b/ErsatzTV.Core/Scheduling/BlockScheduling/BlockPlayoutShuffledMediaCollectionEnumerator.cs @@ -45,7 +45,14 @@ public class BlockPlayoutShuffledMediaCollectionEnumerator : IMediaCollectionEnu public Option Current => _shuffled.Any() ? _shuffled[State.Index % _mediaItemCount] : None; public Option CurrentIncludeInProgramGuide { get; } - public void MoveNext() => State.Index++; + public void MoveNext() + { + State.Index++; + if (State.Index % _mediaItemCount == 0) + { + _shuffled = Shuffle(_mediaItems); + } + } public Option MinimumDuration => _lazyMinimumDuration.Value; diff --git a/ErsatzTV.Core/Scheduling/YamlScheduling/EnumeratorCache.cs b/ErsatzTV.Core/Scheduling/YamlScheduling/EnumeratorCache.cs index 60afa2a8..d7aaab6c 100644 --- a/ErsatzTV.Core/Scheduling/YamlScheduling/EnumeratorCache.cs +++ b/ErsatzTV.Core/Scheduling/YamlScheduling/EnumeratorCache.cs @@ -1,6 +1,7 @@ using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Core.Interfaces.Scheduling; +using ErsatzTV.Core.Scheduling.BlockScheduling; using ErsatzTV.Core.Scheduling.YamlScheduling.Models; namespace ErsatzTV.Core.Scheduling.YamlScheduling; @@ -48,7 +49,7 @@ public class EnumeratorCache(IMediaCollectionRepository mediaCollectionRepositor private async Task> GetEnumeratorForContent( YamlPlayoutContext context, string contentKey, - CancellationToken cancellationToken) + CancellationToken _) { int index = context.Definition.Content.FindIndex(c => c.Key == contentKey); if (index < 0) @@ -82,7 +83,7 @@ public class EnumeratorCache(IMediaCollectionRepository mediaCollectionRepositor List groupedMediaItems = keepMultiPartEpisodesTogether ? MultiPartEpisodeGrouper.GroupMediaItems(items, treatCollectionsAsShows: false) : items.Map(mi => new GroupedMediaItem(mi, null)).ToList(); - return new ShuffledMediaCollectionEnumerator(groupedMediaItems, state, cancellationToken); + return new BlockPlayoutShuffledMediaCollectionEnumerator(groupedMediaItems, state); } return Option.None; diff --git a/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutAllHandler.cs b/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutAllHandler.cs index e2ff7ff2..3238c7c1 100644 --- a/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutAllHandler.cs +++ b/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutAllHandler.cs @@ -42,7 +42,7 @@ public class YamlPlayoutAllHandler(EnumeratorCache enumeratorCache) : YamlPlayou InPoint = TimeSpan.Zero, OutPoint = itemDuration, FillerKind = GetFillerKind(all), - //CustomTitle = scheduleItem.CustomTitle, + CustomTitle = string.IsNullOrWhiteSpace(all.CustomTitle) ? null : all.CustomTitle, //WatermarkId = scheduleItem.WatermarkId, //PreferredAudioLanguageCode = scheduleItem.PreferredAudioLanguageCode, //PreferredAudioTitle = scheduleItem.PreferredAudioTitle, diff --git a/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutApplyHistoryHandler.cs b/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutApplyHistoryHandler.cs index dafd8ba1..db362235 100644 --- a/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutApplyHistoryHandler.cs +++ b/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutApplyHistoryHandler.cs @@ -53,11 +53,17 @@ public class YamlPlayoutApplyHistoryHandler(EnumeratorCache enumeratorCache) { logger.LogDebug("History is applicable: {When}: {History}", h.When, h.Details); - HistoryDetails.MoveToNextItem( - collectionItems, - h.Details, - enumerator, - playbackOrder); + enumerator.ResetState( + new CollectionEnumeratorState { Seed = enumerator.State.Seed, Index = h.Index + 1 }); + + if (playbackOrder is PlaybackOrder.Chronological) + { + HistoryDetails.MoveToNextItem( + collectionItems, + h.Details, + enumerator, + playbackOrder); + } } } diff --git a/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutCountHandler.cs b/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutCountHandler.cs index fbb1373f..f541d117 100644 --- a/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutCountHandler.cs +++ b/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutCountHandler.cs @@ -42,7 +42,7 @@ public class YamlPlayoutCountHandler(EnumeratorCache enumeratorCache) : YamlPlay InPoint = TimeSpan.Zero, OutPoint = itemDuration, FillerKind = GetFillerKind(count), - //CustomTitle = scheduleItem.CustomTitle, + CustomTitle = string.IsNullOrWhiteSpace(count.CustomTitle) ? null : count.CustomTitle, //WatermarkId = scheduleItem.WatermarkId, //PreferredAudioLanguageCode = scheduleItem.PreferredAudioLanguageCode, //PreferredAudioTitle = scheduleItem.PreferredAudioTitle, diff --git a/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutDurationHandler.cs b/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutDurationHandler.cs index 71e57fe4..492b6a7a 100644 --- a/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutDurationHandler.cs +++ b/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutDurationHandler.cs @@ -52,6 +52,7 @@ public class YamlPlayoutDurationHandler(EnumeratorCache enumeratorCache) : YamlP duration.Trim, duration.OfflineTail, GetFillerKind(duration), + duration.CustomTitle, enumerator, fallbackEnumerator); @@ -70,6 +71,7 @@ public class YamlPlayoutDurationHandler(EnumeratorCache enumeratorCache) : YamlP bool trim, bool offlineTail, FillerKind fillerKind, + string customTitle, IMediaCollectionEnumerator enumerator, Option fallbackEnumerator) { @@ -89,7 +91,8 @@ public class YamlPlayoutDurationHandler(EnumeratorCache enumeratorCache) : YamlP InPoint = TimeSpan.Zero, OutPoint = itemDuration, GuideGroup = context.NextGuideGroup(), - FillerKind = fillerKind + FillerKind = fillerKind, + CustomTitle = string.IsNullOrWhiteSpace(customTitle) ? null : customTitle //DisableWatermarks = !allowWatermarks }; diff --git a/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutPadToNextHandler.cs b/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutPadToNextHandler.cs index a1d04c9b..5e4359a2 100644 --- a/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutPadToNextHandler.cs +++ b/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutPadToNextHandler.cs @@ -60,6 +60,7 @@ public class YamlPlayoutPadToNextHandler(EnumeratorCache enumeratorCache) : Yaml padToNext.Trim, offlineTail: true, GetFillerKind(padToNext), + padToNext.CustomTitle, enumerator, fallbackEnumerator); diff --git a/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutPadUntilHandler.cs b/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutPadUntilHandler.cs index 80045b3d..50d5cdad 100644 --- a/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutPadUntilHandler.cs +++ b/ErsatzTV.Core/Scheduling/YamlScheduling/Handlers/YamlPlayoutPadUntilHandler.cs @@ -70,6 +70,7 @@ public class YamlPlayoutPadUntilHandler(EnumeratorCache enumeratorCache) : YamlP padUntil.Trim, offlineTail: true, GetFillerKind(padUntil), + padUntil.CustomTitle, enumerator, fallbackEnumerator); diff --git a/ErsatzTV.Core/Scheduling/YamlScheduling/Models/YamlPlayoutInstruction.cs b/ErsatzTV.Core/Scheduling/YamlScheduling/Models/YamlPlayoutInstruction.cs index 9411ec80..aad02572 100644 --- a/ErsatzTV.Core/Scheduling/YamlScheduling/Models/YamlPlayoutInstruction.cs +++ b/ErsatzTV.Core/Scheduling/YamlScheduling/Models/YamlPlayoutInstruction.cs @@ -11,6 +11,9 @@ public class YamlPlayoutInstruction [YamlMember(Alias = "filler_kind", ApplyNamingConventions = false)] public string FillerKind { get; set; } + [YamlMember(Alias = "custom_title", ApplyNamingConventions = false)] + public string CustomTitle { get; set; } + [YamlIgnore] public string SequenceKey { get; set; }