@ -11,10 +11,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
@@ -11,10 +11,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Properly detect QSV capabilities for Intel 10th gen and older devices; previously they always used software transcoding
- Fix block scheduler deleting the current hour's playout items, taking the channel offline until the next block
- Fix playlists and marathons not continuing from the saved position after a restart or a playout rebuild
- Affects playlists and marathons in sequential and scripted schedules, and playlists used as block deco filler
- Episodes that had already played would repeat, and others would be skipped each time the collection came up
- Only the last collection of a playlist kept its position (regression from `v26.7.0`)
- Sequential and scripted schedules first build after upgrading may still start at the wrong item; every build after that will be correct
- Fix shuffled playlists and marathons (`shuffle_groups`) playing the wrong content after the first full cycle
- Fix multiple causes of playout build hangs
- Fix **Skip Missing Items** being ignored by multi-collection shuffle, shuffle in order, and playlists
- Sequential schedules:
- Fix `shuffle_sequence` losing the shuffled order at the end of each build; previously the next build continued in schedule file order
- Fix `shuffle_sequence` deleting the instructions between two uses of the same sequence
@ -8,7 +8,7 @@ public record ContentMarathon
@@ -8,7 +8,7 @@ public record ContentMarathon
publicrequiredstringKey{get;set;}
[Description(
"Tells the scheduler how to group the combined content (returned from all guids and searches). Valid values are show, season, artist and album.")]
"Tells the scheduler how to group the combined content (returned from all guids and searches). Valid values are show, season, artist, album and director.")]
publicrequiredstringGroupBy{get;set;}
[Description("Playback order within each group; only chronological and shuffle are currently supported")]
@ -39,7 +39,7 @@ public sealed class ChronologicalMediaCollectionEnumerator : IMediaCollectionEnu
@@ -39,7 +39,7 @@ public sealed class ChronologicalMediaCollectionEnumerator : IMediaCollectionEnu
@ -84,4 +84,8 @@ public sealed class ChronologicalMediaCollectionEnumerator : IMediaCollectionEnu
@@ -84,4 +84,8 @@ public sealed class ChronologicalMediaCollectionEnumerator : IMediaCollectionEnu
@ -35,7 +35,7 @@ public class CustomOrderCollectionEnumerator : IMediaCollectionEnumerator
@@ -35,7 +35,7 @@ public class CustomOrderCollectionEnumerator : IMediaCollectionEnumerator
@ -55,4 +55,8 @@ public class CustomOrderCollectionEnumerator : IMediaCollectionEnumerator
@@ -55,4 +55,8 @@ public class CustomOrderCollectionEnumerator : IMediaCollectionEnumerator
@ -94,6 +96,9 @@ public class MarathonHelper(IMediaCollectionRepository mediaCollectionRepository
@@ -94,6 +96,9 @@ public class MarathonHelper(IMediaCollectionRepository mediaCollectionRepository
@ -121,6 +126,11 @@ public class MarathonHelper(IMediaCollectionRepository mediaCollectionRepository
@@ -121,6 +126,11 @@ public class MarathonHelper(IMediaCollectionRepository mediaCollectionRepository
@ -186,7 +196,7 @@ public class MarathonHelper(IMediaCollectionRepository mediaCollectionRepository
@@ -186,7 +196,7 @@ public class MarathonHelper(IMediaCollectionRepository mediaCollectionRepository
@ -30,9 +31,12 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
@@ -30,9 +31,12 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
@ -76,6 +80,12 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
@@ -76,6 +80,12 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
@ -122,14 +132,44 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
@@ -122,14 +132,44 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
@ -145,7 +185,8 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
@@ -145,7 +185,8 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
_sortedEnumerators=[],
_idsToIncludeInEPG=[],
_shufflePlaylistItems=shufflePlaylistItems,
_batchSize=batchSize
_batchSize=batchSize,
_cancellationToken=cancellationToken
};
// random start points must be applied on every build, not just the first
@ -169,7 +210,11 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
@@ -169,7 +210,11 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
@ -208,6 +253,7 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
@@ -208,6 +253,7 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
@ -237,7 +283,11 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
@@ -237,7 +283,11 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
@ -259,10 +309,8 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
@@ -259,10 +309,8 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
@ -275,18 +323,17 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
@@ -275,18 +323,17 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
@ -311,13 +358,8 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
@@ -311,13 +358,8 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
@ -360,6 +402,12 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
@@ -360,6 +402,12 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
// a record compares by value. If every entry equals the last one, the loop below cannot end.
if(_enumeratorsInPlaylistOrder.All(e=>e==last))
{
return[.._enumeratorsInPlaylistOrder];
}
do
{
intn=copy.Length;
@ -369,10 +417,14 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
@@ -369,10 +417,14 @@ public class PlaylistEnumerator : IMediaCollectionEnumerator
@ -41,7 +41,7 @@ public sealed class SeasonEpisodeMediaCollectionEnumerator : IMediaCollectionEnu
@@ -41,7 +41,7 @@ public sealed class SeasonEpisodeMediaCollectionEnumerator : IMediaCollectionEnu
@ -66,4 +66,8 @@ public sealed class SeasonEpisodeMediaCollectionEnumerator : IMediaCollectionEnu
@@ -66,4 +66,8 @@ public sealed class SeasonEpisodeMediaCollectionEnumerator : IMediaCollectionEnu
@ -131,6 +131,15 @@ public class EnumeratorCache(IMediaCollectionRepository mediaCollectionRepositor
@@ -131,6 +131,15 @@ public class EnumeratorCache(IMediaCollectionRepository mediaCollectionRepositor
state,
cancellationToken);
if(maybeResult.IsNone)
{
logger.LogWarning(
"Unable to add marathon with key {Key}; group_by {GroupBy} is not one of {ValidValues}",
@ -67,11 +67,10 @@ public class YamlPlayoutApplyHistoryHandler(EnumeratorCache enumeratorCache)
@@ -67,11 +67,10 @@ public class YamlPlayoutApplyHistoryHandler(EnumeratorCache enumeratorCache)
@ -103,6 +102,19 @@ public class YamlPlayoutApplyHistoryHandler(EnumeratorCache enumeratorCache)
@@ -103,6 +102,19 @@ public class YamlPlayoutApplyHistoryHandler(EnumeratorCache enumeratorCache)
// h.Details,
// h.IsCurrentChild);
// a shuffled child gets a new seed each time it wraps.
// the replay from the cycle start cannot make that order again.
if(itemPlaybackOrderisPlaybackOrder.Shuffle)
{
childEnumerator.ResetState(
newCollectionEnumeratorState
{
Seed=h.Seed??childEnumerator.State.Seed,
Index=h.Index,
Started=childEnumerator.State.Started
});
}
// the collection may have changed since the last build, so the replayed
@ -118,7 +130,7 @@ public class YamlPlayoutApplyHistoryHandler(EnumeratorCache enumeratorCache)
@@ -118,7 +130,7 @@ public class YamlPlayoutApplyHistoryHandler(EnumeratorCache enumeratorCache)
// the playlist order may have changed since the last build
@ -84,6 +84,7 @@ public abstract class YamlPlayoutContentHandler(EnumeratorCache enumeratorCache)
@@ -84,6 +84,7 @@ public abstract class YamlPlayoutContentHandler(EnumeratorCache enumeratorCache)
PlayoutId=context.Playout.Id,
PlaybackOrder=playbackOrder,
Index=playlistEnumerator.State.Index,
Seed=playlistEnumerator.State.Seed,
When=playoutItem.StartOffset.UtcDateTime,
Finish=playoutItem.FinishOffset.UtcDateTime,
Key=historyKey,
@ -105,6 +106,7 @@ public abstract class YamlPlayoutContentHandler(EnumeratorCache enumeratorCache)
@@ -105,6 +106,7 @@ public abstract class YamlPlayoutContentHandler(EnumeratorCache enumeratorCache)
@ -68,6 +68,12 @@ public class ScriptedScheduleController(IScriptedPlayoutBuilderService scriptedP
@@ -68,6 +68,12 @@ public class ScriptedScheduleController(IScriptedPlayoutBuilderService scriptedP