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