|
|
|
@ -45,6 +45,7 @@ public class TemplatePlayoutBuilder( |
|
|
|
// load content and content enumerators on demand
|
|
|
|
// load content and content enumerators on demand
|
|
|
|
Dictionary<string, IMediaCollectionEnumerator> enumerators = new(); |
|
|
|
Dictionary<string, IMediaCollectionEnumerator> enumerators = new(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int itemsAfterRepeat = playout.Items.Count; |
|
|
|
var index = 0; |
|
|
|
var index = 0; |
|
|
|
while (currentTime < finish) |
|
|
|
while (currentTime < finish) |
|
|
|
{ |
|
|
|
{ |
|
|
|
@ -60,38 +61,49 @@ public class TemplatePlayoutBuilder( |
|
|
|
if (playoutItem is PlayoutTemplateRepeatItem) |
|
|
|
if (playoutItem is PlayoutTemplateRepeatItem) |
|
|
|
{ |
|
|
|
{ |
|
|
|
index = 0; |
|
|
|
index = 0; |
|
|
|
|
|
|
|
if (playout.Items.Count == itemsAfterRepeat) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
logger.LogWarning("Repeat encountered without adding any playout items; aborting"); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
itemsAfterRepeat = playout.Items.Count; |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!enumerators.TryGetValue(playoutItem.Content, out IMediaCollectionEnumerator enumerator)) |
|
|
|
Option<IMediaCollectionEnumerator> maybeEnumerator = await GetCachedEnumeratorForContent( |
|
|
|
{ |
|
|
|
playout, |
|
|
|
Option<IMediaCollectionEnumerator> maybeEnumerator = |
|
|
|
playoutTemplate, |
|
|
|
await GetEnumeratorForContent(playout, playoutItem.Content, playoutTemplate, cancellationToken); |
|
|
|
enumerators, |
|
|
|
|
|
|
|
playoutItem.Content, |
|
|
|
|
|
|
|
cancellationToken); |
|
|
|
|
|
|
|
|
|
|
|
if (maybeEnumerator.IsNone) |
|
|
|
if (maybeEnumerator.IsNone) |
|
|
|
{ |
|
|
|
{ |
|
|
|
logger.LogWarning("Unable to locate content with key {Key}", playoutItem.Content); |
|
|
|
logger.LogWarning("Unable to locate content with key {Key}", playoutItem.Content); |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach (IMediaCollectionEnumerator e in maybeEnumerator) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
enumerator = maybeEnumerator.ValueUnsafe(); |
|
|
|
|
|
|
|
enumerators.Add(playoutItem.Content, enumerator); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IMediaCollectionEnumerator enumerator = maybeEnumerator.ValueUnsafe(); |
|
|
|
|
|
|
|
|
|
|
|
switch (playoutItem) |
|
|
|
switch (playoutItem) |
|
|
|
{ |
|
|
|
{ |
|
|
|
case PlayoutTemplateCountItem count: |
|
|
|
case PlayoutTemplateCountItem count: |
|
|
|
currentTime = PlayoutTemplateSchedulerCount.Schedule(playout, currentTime, count, enumerator); |
|
|
|
currentTime = PlayoutTemplateSchedulerCount.Schedule(playout, currentTime, count, enumerator); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case PlayoutTemplatePadToNextItem padToNext: |
|
|
|
case PlayoutTemplatePadToNextItem padToNext: |
|
|
|
|
|
|
|
Option<IMediaCollectionEnumerator> fallbackEnumerator = await GetCachedEnumeratorForContent( |
|
|
|
|
|
|
|
playout, |
|
|
|
|
|
|
|
playoutTemplate, |
|
|
|
|
|
|
|
enumerators, |
|
|
|
|
|
|
|
padToNext.Fallback, |
|
|
|
|
|
|
|
cancellationToken); |
|
|
|
currentTime = PlayoutTemplateSchedulerPadToNext.Schedule( |
|
|
|
currentTime = PlayoutTemplateSchedulerPadToNext.Schedule( |
|
|
|
playout, |
|
|
|
playout, |
|
|
|
currentTime, |
|
|
|
currentTime, |
|
|
|
padToNext, |
|
|
|
padToNext, |
|
|
|
enumerator); |
|
|
|
enumerator, |
|
|
|
|
|
|
|
fallbackEnumerator); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -106,6 +118,38 @@ public class TemplatePlayoutBuilder( |
|
|
|
.GetValue<int>(ConfigElementKey.PlayoutDaysToBuild) |
|
|
|
.GetValue<int>(ConfigElementKey.PlayoutDaysToBuild) |
|
|
|
.IfNoneAsync(2); |
|
|
|
.IfNoneAsync(2); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private async Task<Option<IMediaCollectionEnumerator>> GetCachedEnumeratorForContent( |
|
|
|
|
|
|
|
Playout playout, |
|
|
|
|
|
|
|
PlayoutTemplate playoutTemplate, |
|
|
|
|
|
|
|
Dictionary<string, IMediaCollectionEnumerator> enumerators, |
|
|
|
|
|
|
|
string contentKey, |
|
|
|
|
|
|
|
CancellationToken cancellationToken) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(contentKey)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return Option<IMediaCollectionEnumerator>.None; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!enumerators.TryGetValue(contentKey, out IMediaCollectionEnumerator enumerator)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Option<IMediaCollectionEnumerator> maybeEnumerator = |
|
|
|
|
|
|
|
await GetEnumeratorForContent(playout, contentKey, playoutTemplate, cancellationToken); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (maybeEnumerator.IsNone) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return Option<IMediaCollectionEnumerator>.None; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach (IMediaCollectionEnumerator e in maybeEnumerator) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
enumerator = maybeEnumerator.ValueUnsafe(); |
|
|
|
|
|
|
|
enumerators.Add(contentKey, enumerator); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return Some(enumerator); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private async Task<Option<IMediaCollectionEnumerator>> GetEnumeratorForContent( |
|
|
|
private async Task<Option<IMediaCollectionEnumerator>> GetEnumeratorForContent( |
|
|
|
Playout playout, |
|
|
|
Playout playout, |
|
|
|
string contentKey, |
|
|
|
string contentKey, |
|
|
|
@ -156,6 +200,4 @@ public class TemplatePlayoutBuilder( |
|
|
|
|
|
|
|
|
|
|
|
return deserializer.Deserialize<PlayoutTemplate>(yaml); |
|
|
|
return deserializer.Deserialize<PlayoutTemplate>(yaml); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|