Browse Source

skip zero duration items when building playouts (#236)

pull/237/head
Jason Dove 4 years ago committed by GitHub
parent
commit
eee10dee22
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      CHANGELOG.md
  2. 23
      ErsatzTV.Core.Tests/Scheduling/PlayoutBuilderTests.cs
  3. 39
      ErsatzTV.Core/Scheduling/PlayoutBuilder.cs

8
CHANGELOG.md

@ -3,7 +3,13 @@ All notable changes to this project will be documented in this file. @@ -3,7 +3,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## Unreleased
## [Unreleased]
### Changed
- Skip zero duration items when building a playout, rather than aborting the playout build
### Fixed
- Fix edge case where a playout rebuild would get stuck and block all other playouts and library scans
## [0.0.41-prealpha] - 2021-05-30
### Added

23
ErsatzTV.Core.Tests/Scheduling/PlayoutBuilderTests.cs

@ -39,7 +39,7 @@ namespace ErsatzTV.Core.Tests.Scheduling @@ -39,7 +39,7 @@ namespace ErsatzTV.Core.Tests.Scheduling
[Test]
[Timeout(2000)]
public async Task ZeroDurationItem_Should_Abort()
public async Task OnlyZeroDurationItem_Should_Abort()
{
var mediaItems = new List<MediaItem>
{
@ -55,6 +55,27 @@ namespace ErsatzTV.Core.Tests.Scheduling @@ -55,6 +55,27 @@ namespace ErsatzTV.Core.Tests.Scheduling
result.Items.Should().BeNull();
}
[Test]
public async Task ZeroDurationItem_Should_BeSkipped()
{
var mediaItems = new List<MediaItem>
{
TestMovie(1, TimeSpan.Zero, DateTime.Today),
TestMovie(2, TimeSpan.FromHours(6), DateTime.Today)
};
(PlayoutBuilder builder, Playout playout) = TestDataFloodForItems(mediaItems, PlaybackOrder.Random);
DateTimeOffset start = HoursAfterMidnight(0);
DateTimeOffset finish = start + TimeSpan.FromHours(6);
Playout result = await builder.BuildPlayoutItems(playout, start, finish);
result.Items.Count.Should().Be(1);
result.Items.Head().MediaItemId.Should().Be(2);
result.Items.Head().StartOffset.TimeOfDay.Should().Be(TimeSpan.Zero);
result.Items.Head().FinishOffset.TimeOfDay.Should().Be(TimeSpan.FromHours(6));
}
[Test]
public async Task InitialFlood_Should_StartAtMidnight()
{

39
ErsatzTV.Core/Scheduling/PlayoutBuilder.cs

@ -80,17 +80,52 @@ namespace ErsatzTV.Core.Scheduling @@ -80,17 +80,52 @@ namespace ErsatzTV.Core.Scheduling
playout.Channel.Number,
playout.Channel.Name);
foreach ((CollectionKey _, List<MediaItem> items) in collectionMediaItems)
{
var zeroItems = new List<MediaItem>();
foreach (MediaItem item in items)
{
bool isZero = item switch
{
Movie m => await m.MediaVersions.Map(v => v.Duration).HeadOrNone().IfNoneAsync(TimeSpan.Zero) ==
TimeSpan.Zero,
Episode e => await e.MediaVersions.Map(v => v.Duration).HeadOrNone()
.IfNoneAsync(TimeSpan.Zero) ==
TimeSpan.Zero,
MusicVideo mv => await mv.MediaVersions.Map(v => v.Duration).HeadOrNone()
.IfNoneAsync(TimeSpan.Zero) ==
TimeSpan.Zero,
_ => true
};
if (isZero)
{
_logger.LogWarning(
"Skipping media item with zero duration {MediaItem} - {MediaItemTitle}",
item.Id,
DisplayTitle(item));
zeroItems.Add(item);
}
}
items.RemoveAll(i => zeroItems.Contains(i));
}
// this guard needs to be below the place where we modify the collections (by removing zero-duration items)
Option<CollectionKey> emptyCollection =
collectionMediaItems.Find(c => !c.Value.Any()).Map(c => c.Key);
if (emptyCollection.IsSome)
{
_logger.LogError(
"Unable to rebuild playout; collection {@CollectionKey} has no items!",
"Unable to rebuild playout; collection {@CollectionKey} has no valid items!",
emptyCollection.ValueUnsafe());
return playout;
}
// leaving this guard in for a while to ensure the zero item removal is working properly
Option<CollectionKey> zeroDurationCollection = collectionMediaItems.Find(
c => c.Value.Any(
mi => mi switch
@ -106,7 +141,7 @@ namespace ErsatzTV.Core.Scheduling @@ -106,7 +141,7 @@ namespace ErsatzTV.Core.Scheduling
if (zeroDurationCollection.IsSome)
{
_logger.LogError(
"Unable to rebuild playout; collection {@CollectionKey} contains items with zero duration!",
"BUG: Unable to rebuild playout; collection {@CollectionKey} contains items with zero duration!",
zeroDurationCollection.ValueUnsafe());
return playout;

Loading…
Cancel
Save