Stream custom live channels using your own media
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

74 lines
2.3 KiB

using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Extensions;
using ErsatzTV.Core.Interfaces.Scheduling;
namespace ErsatzTV.Core.Scheduling.BlockScheduling;
public class BlockPlayoutShuffledMediaCollectionEnumerator : IMediaCollectionEnumerator
{
private readonly Lazy<Option<TimeSpan>> _lazyMinimumDuration;
private readonly int _mediaItemCount;
private readonly IList<GroupedMediaItem> _mediaItems;
private IList<MediaItem> _shuffled;
public BlockPlayoutShuffledMediaCollectionEnumerator(
IList<GroupedMediaItem> mediaItems,
CollectionEnumeratorState state)
{
CurrentIncludeInProgramGuide = Option<bool>.None;
_mediaItems = mediaItems;
_mediaItemCount = _mediaItems.Sum(i => 1 + Optional(i.Additional).Flatten().Count());
State = state;
_shuffled = Shuffle(_mediaItems);
_lazyMinimumDuration =
new Lazy<Option<TimeSpan>>(
() => _shuffled.Bind(i => i.GetNonZeroDuration()).OrderBy(identity).HeadOrNone());
}
public void ResetState(CollectionEnumeratorState state)
{
// only re-shuffle if needed
if (State.Seed != state.Seed || State.Index != state.Index)
{
State.Seed = state.Seed;
State.Index = state.Index;
_shuffled = Shuffle(_mediaItems);
}
}
public CollectionEnumeratorState State { get; }
public Option<MediaItem> Current => _shuffled.Any() ? _shuffled[State.Index % _mediaItemCount] : None;
public Option<bool> CurrentIncludeInProgramGuide { get; }
public void MoveNext()
{
State.Index++;
if (State.Index % _mediaItemCount == 0)
{
_shuffled = Shuffle(_mediaItems);
}
}
public Option<TimeSpan> MinimumDuration => _lazyMinimumDuration.Value;
public int Count => _shuffled.Count;
private IList<MediaItem> Shuffle(IList<GroupedMediaItem> list)
{
var copy = new GroupedMediaItem[list.Count];
var superShuffle = new SuperShuffle();
for (var i = 0; i < list.Count; i++)
{
int toSelect = superShuffle.Shuffle(i, State.Seed + State.Index / list.Count, list.Count);
copy[i] = list[toSelect];
}
return GroupedMediaItem.FlattenGroups(copy, _mediaItemCount);
}
}