Browse Source

pass chapter title to filler expression

pull/2803/head
Jason Dove 6 months ago
parent
commit
90f3c4bb4d
No known key found for this signature in database
  1. 3
      CHANGELOG.md
  2. 102
      ErsatzTV.Core.Tests/Scheduling/FillerExpressionTests.cs
  3. 10
      ErsatzTV.Core/Scheduling/FillerExpression.cs

3
CHANGELOG.md

@ -29,6 +29,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). @@ -29,6 +29,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- `Normalize Video` (default: true) - normalizes video streams, or stream copies when disabled
- `Normalize Colors` (default: true) - normalizes color parameters when enabled
- Disabling any of these options may have a significant performance benefit *at the expense of stream stability*
- Add `title` to filler expression
- This can be used to include or exclude chapters with specific (case-insensitive) titles
- E.g. `title == 'here'`, `title != 'not here'`, `title like '%here%'`
### Changed
- Disable automatic artwork database cleanup

102
ErsatzTV.Core.Tests/Scheduling/FillerExpressionTests.cs

@ -75,4 +75,106 @@ public class FillerExpressionTests @@ -75,4 +75,106 @@ public class FillerExpressionTests
result[1].EndTime.ShouldBe(TimeSpan.FromMinutes(20));
result[2].EndTime.ShouldBe(TimeSpan.FromMinutes(30));
}
[Test]
public void Match_Case_Insensitive_Titles_Expression()
{
// 30 min content
var playoutItem = new PlayoutItem { Start = DateTimeOffset.Now.UtcDateTime };
playoutItem.Finish = playoutItem.Start + TimeSpan.FromMinutes(30);
// chapters every 5 min
var chapters = new List<MediaChapter>
{
new() { ChapterId = 1, StartTime = TimeSpan.Zero, EndTime = TimeSpan.FromMinutes(5), Title = "Not Here" },
new() { ChapterId = 2, StartTime = TimeSpan.FromMinutes(5), EndTime = TimeSpan.FromMinutes(10), Title = "Here" },
new() { ChapterId = 3, StartTime = TimeSpan.FromMinutes(10), EndTime = TimeSpan.FromMinutes(15), Title = "Not Here" },
new() { ChapterId = 4, StartTime = TimeSpan.FromMinutes(15), EndTime = TimeSpan.FromMinutes(20), Title = "Here" },
new() { ChapterId = 5, StartTime = TimeSpan.FromMinutes(20), EndTime = TimeSpan.FromMinutes(25), Title = "Not Here" },
new() { ChapterId = 6, StartTime = TimeSpan.FromMinutes(25), EndTime = TimeSpan.FromMinutes(30), Title = "Here" }
};
var fillerPreset = new FillerPreset
{
FillerKind = FillerKind.MidRoll,
Expression =
"title == 'here'"
};
List<MediaChapter> result = FillerExpression.FilterChapters(fillerPreset.Expression, chapters, playoutItem);
result.Count.ShouldBe(3);
result[0].EndTime.ShouldBe(TimeSpan.FromMinutes(10));
result[1].EndTime.ShouldBe(TimeSpan.FromMinutes(20));
result[2].EndTime.ShouldBe(TimeSpan.FromMinutes(30));
}
[Test]
public void Exclude_Case_Insensitive_Titles_Expression()
{
// 30 min content
var playoutItem = new PlayoutItem { Start = DateTimeOffset.Now.UtcDateTime };
playoutItem.Finish = playoutItem.Start + TimeSpan.FromMinutes(30);
// chapters every 5 min
var chapters = new List<MediaChapter>
{
new() { ChapterId = 1, StartTime = TimeSpan.Zero, EndTime = TimeSpan.FromMinutes(5), Title = "Not Here" },
new() { ChapterId = 2, StartTime = TimeSpan.FromMinutes(5), EndTime = TimeSpan.FromMinutes(10), Title = "Here" },
new() { ChapterId = 3, StartTime = TimeSpan.FromMinutes(10), EndTime = TimeSpan.FromMinutes(15), Title = "Not Here" },
new() { ChapterId = 4, StartTime = TimeSpan.FromMinutes(15), EndTime = TimeSpan.FromMinutes(20), Title = "Here" },
new() { ChapterId = 5, StartTime = TimeSpan.FromMinutes(20), EndTime = TimeSpan.FromMinutes(25), Title = "Not Here" },
new() { ChapterId = 6, StartTime = TimeSpan.FromMinutes(25), EndTime = TimeSpan.FromMinutes(30), Title = "Here" }
};
var fillerPreset = new FillerPreset
{
FillerKind = FillerKind.MidRoll,
Expression =
"title != 'not here'"
};
List<MediaChapter> result = FillerExpression.FilterChapters(fillerPreset.Expression, chapters, playoutItem);
result.Count.ShouldBe(3);
result[0].EndTime.ShouldBe(TimeSpan.FromMinutes(10));
result[1].EndTime.ShouldBe(TimeSpan.FromMinutes(20));
result[2].EndTime.ShouldBe(TimeSpan.FromMinutes(30));
}
[Test]
public void Include_Partial_Case_Insensitive_Titles_Expression()
{
// 30 min content
var playoutItem = new PlayoutItem { Start = DateTimeOffset.Now.UtcDateTime };
playoutItem.Finish = playoutItem.Start + TimeSpan.FromMinutes(30);
// chapters every 5 min
var chapters = new List<MediaChapter>
{
new() { ChapterId = 1, StartTime = TimeSpan.Zero, EndTime = TimeSpan.FromMinutes(5), Title = "Not Here" },
new() { ChapterId = 2, StartTime = TimeSpan.FromMinutes(5), EndTime = TimeSpan.FromMinutes(10), Title = "Here" },
new() { ChapterId = 3, StartTime = TimeSpan.FromMinutes(10), EndTime = TimeSpan.FromMinutes(15), Title = "Not Here" },
new() { ChapterId = 4, StartTime = TimeSpan.FromMinutes(15), EndTime = TimeSpan.FromMinutes(20), Title = "Here" },
new() { ChapterId = 5, StartTime = TimeSpan.FromMinutes(20), EndTime = TimeSpan.FromMinutes(25), Title = "Not Here" },
new() { ChapterId = 6, StartTime = TimeSpan.FromMinutes(25), EndTime = TimeSpan.FromMinutes(30), Title = "Here" }
};
var fillerPreset = new FillerPreset
{
FillerKind = FillerKind.MidRoll,
Expression =
"title like \"%here%\""
};
List<MediaChapter> result = FillerExpression.FilterChapters(fillerPreset.Expression, chapters, playoutItem);
result.Count.ShouldBe(6);
result[0].EndTime.ShouldBe(TimeSpan.FromMinutes(5));
result[1].EndTime.ShouldBe(TimeSpan.FromMinutes(10));
result[2].EndTime.ShouldBe(TimeSpan.FromMinutes(15));
result[3].EndTime.ShouldBe(TimeSpan.FromMinutes(20));
result[4].EndTime.ShouldBe(TimeSpan.FromMinutes(25));
result[5].EndTime.ShouldBe(TimeSpan.FromMinutes(30));
}
}

10
ErsatzTV.Core/Scheduling/FillerExpression.cs

@ -15,7 +15,7 @@ public static class FillerExpression @@ -15,7 +15,7 @@ public static class FillerExpression
return effectiveChapters;
}
var chapterPoints = effectiveChapters.Map(c => c.EndTime).SkipLast().ToList();
var candidateChapters = effectiveChapters.SkipLast().ToList();
var newChapters = new List<MediaChapter>();
@ -26,10 +26,11 @@ public static class FillerExpression @@ -26,10 +26,11 @@ public static class FillerExpression
double contentDuration = (playoutItem.FinishOffset - playoutItem.StartOffset).TotalSeconds;
var matches = 0;
for (var index = 0; index < chapterPoints.Count; index++)
for (var index = 0; index < candidateChapters.Count; index++)
{
TimeSpan chapterPoint = chapterPoints[index];
var expression = new Expression(fillerExpression);
MediaChapter chapter = candidateChapters[index];
TimeSpan chapterPoint = chapter.EndTime;
var expression = new Expression(fillerExpression, ExpressionOptions.CaseInsensitiveStringComparer);
int chapterNum = index + 1;
double sinceLastFiller = chapterPoint.TotalSeconds - lastFiller;
int matchedPoints = matches;
@ -45,6 +46,7 @@ public static class FillerExpression @@ -45,6 +46,7 @@ public static class FillerExpression
"matched_points" => matchedPoints,
"point" => chapterPoint.TotalSeconds,
"num" => chapterNum,
"title" => chapter.Title ?? string.Empty,
_ => e.Result
};
};

Loading…
Cancel
Save