From a8b658a5eaee291e45f7491c273ec5549077c833 Mon Sep 17 00:00:00 2001
From: Jason Dove <1695733+jasongdove@users.noreply.github.com>
Date: Tue, 16 Jul 2024 12:21:52 -0500
Subject: [PATCH] add "on demand" channel progress mode (#1790)
* update dependencies
* add channel progress mode
* implement on demand channel progress
* update changelog
---
CHANGELOG.md | 7 +
.../Channels/ChannelViewModel.cs | 1 +
.../Channels/Commands/CreateChannel.cs | 1 +
.../Channels/Commands/CreateChannelHandler.cs | 1 +
.../Channels/Commands/UpdateChannel.cs | 1 +
.../Channels/Commands/UpdateChannelHandler.cs | 1 +
ErsatzTV.Application/Channels/Mapper.cs | 1 +
.../ErsatzTV.Application.csproj | 6 +-
.../Commands/CreateFloodPlayoutHandler.cs | 4 +
.../Commands/TimeShiftOnDemandPlayout.cs | 6 +
.../TimeShiftOnDemandPlayoutHandler.cs | 41 +
.../UpdateExternalJsonPlayoutHandler.cs | 3 +-
.../Commands/UpdateOnDemandCheckpoint.cs | 4 +
.../UpdateOnDemandCheckpointHandler.cs | 62 +
.../Playouts/Commands/UpdatePlayoutHandler.cs | 3 +-
.../Playouts/PlayoutNameViewModel.cs | 6 +-
.../Playouts/Queries/GetAllPlayoutsHandler.cs | 3 +-
.../Streaming/HlsSessionWorker.cs | 17 +-
.../Streaming/HlsSessionWorkerV2.cs | 17 +-
.../ErsatzTV.Core.Tests.csproj | 6 +-
.../Scheduling/PlayoutBuilderTests.cs | 19 +
.../Scheduling/ScheduleIntegrationTests.cs | 2 +
ErsatzTV.Core/Domain/Channel.cs | 1 +
ErsatzTV.Core/Domain/ChannelProgressMode.cs | 7 +
ErsatzTV.Core/Domain/Playout.cs | 1 +
ErsatzTV.Core/ErsatzTV.Core.csproj | 10 +-
.../Scheduling/IPlayoutTimeShifter.cs | 8 +
ErsatzTV.Core/Scheduling/PlayoutBuilder.cs | 54 +-
.../Scheduling/PlayoutTimeShifter.cs | 90 +
ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj | 2 +-
.../ErsatzTV.Infrastructure.MySql.csproj | 2 +-
...41648_Add_Channel_ProgressMode.Designer.cs | 5802 ++++++++++++++++
...20240716141648_Add_Channel_ProgressMode.cs | 29 +
...Add_Playout_OnDemandCheckpoint.Designer.cs | 5805 +++++++++++++++++
...16155846_Add_Playout_OnDemandCheckpoint.cs | 29 +
.../Migrations/TvContextModelSnapshot.cs | 8 +-
.../ErsatzTV.Infrastructure.Sqlite.csproj | 4 +-
...35729_Add_Channel_ProgressMode.Designer.cs | 5641 ++++++++++++++++
...20240716135729_Add_Channel_ProgressMode.cs | 29 +
...Add_Playout_OnDemandCheckpoint.Designer.cs | 5644 ++++++++++++++++
...16150019_Add_Playout_OnDemandCheckpoint.cs | 29 +
.../Migrations/TvContextModelSnapshot.cs | 8 +-
.../ErsatzTV.Infrastructure.csproj | 16 +-
.../ErsatzTV.Scanner.Tests.csproj | 2 +-
ErsatzTV.Scanner/ErsatzTV.Scanner.csproj | 12 +-
ErsatzTV/ErsatzTV.csproj | 24 +-
ErsatzTV/Pages/ChannelEditor.razor | 5 +
ErsatzTV/Pages/Playouts.razor | 24 +-
ErsatzTV/Services/WorkerService.cs | 3 +
ErsatzTV/Startup.cs | 2 +
ErsatzTV/ViewModels/ChannelEditViewModel.cs | 3 +
51 files changed, 23439 insertions(+), 67 deletions(-)
create mode 100644 ErsatzTV.Application/Playouts/Commands/TimeShiftOnDemandPlayout.cs
create mode 100644 ErsatzTV.Application/Playouts/Commands/TimeShiftOnDemandPlayoutHandler.cs
create mode 100644 ErsatzTV.Application/Playouts/Commands/UpdateOnDemandCheckpoint.cs
create mode 100644 ErsatzTV.Application/Playouts/Commands/UpdateOnDemandCheckpointHandler.cs
create mode 100644 ErsatzTV.Core/Domain/ChannelProgressMode.cs
create mode 100644 ErsatzTV.Core/Interfaces/Scheduling/IPlayoutTimeShifter.cs
create mode 100644 ErsatzTV.Core/Scheduling/PlayoutTimeShifter.cs
create mode 100644 ErsatzTV.Infrastructure.MySql/Migrations/20240716141648_Add_Channel_ProgressMode.Designer.cs
create mode 100644 ErsatzTV.Infrastructure.MySql/Migrations/20240716141648_Add_Channel_ProgressMode.cs
create mode 100644 ErsatzTV.Infrastructure.MySql/Migrations/20240716155846_Add_Playout_OnDemandCheckpoint.Designer.cs
create mode 100644 ErsatzTV.Infrastructure.MySql/Migrations/20240716155846_Add_Playout_OnDemandCheckpoint.cs
create mode 100644 ErsatzTV.Infrastructure.Sqlite/Migrations/20240716135729_Add_Channel_ProgressMode.Designer.cs
create mode 100644 ErsatzTV.Infrastructure.Sqlite/Migrations/20240716135729_Add_Channel_ProgressMode.cs
create mode 100644 ErsatzTV.Infrastructure.Sqlite/Migrations/20240716150019_Add_Playout_OnDemandCheckpoint.Designer.cs
create mode 100644 ErsatzTV.Infrastructure.Sqlite/Migrations/20240716150019_Add_Playout_OnDemandCheckpoint.cs
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f136cf0e..5128d364 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- These libraries will now appear as ETV Other Video libraries
- Items in these libraries will have tag metadata added from folders just like local Other Video libraries
- Thanks @raknam for adding this feature!
+- Add *experimental* support for `On Demand` channel progress
+ - With `On Demand` channel progress, the schedule will only advance when the channel is being streamed
+ - When the channel is idle, the schedule is unmodified and will be shifted forward as needed so no content is missed
+ - Setting a channel to `On Demand` progress will disable alternate schedules
+ - The `On Demand` setting will only be used for `Flood` playouts (NOT `Block` or `External JSON`)
+ - It is NOT recommended to use fixed start times with `On Demand` progress
+ - This will probably be disabled with a future update
### Fixed
- Add basic cache busting to XMLTV image URLs
diff --git a/ErsatzTV.Application/Channels/ChannelViewModel.cs b/ErsatzTV.Application/Channels/ChannelViewModel.cs
index 8faa3f6d..0fc9b999 100644
--- a/ErsatzTV.Application/Channels/ChannelViewModel.cs
+++ b/ErsatzTV.Application/Channels/ChannelViewModel.cs
@@ -12,6 +12,7 @@ public record ChannelViewModel(
string Logo,
string PreferredAudioLanguageCode,
string PreferredAudioTitle,
+ ChannelProgressMode ProgressMode,
StreamingMode StreamingMode,
int? WatermarkId,
int? FallbackFillerId,
diff --git a/ErsatzTV.Application/Channels/Commands/CreateChannel.cs b/ErsatzTV.Application/Channels/Commands/CreateChannel.cs
index e3427b58..b0682ca2 100644
--- a/ErsatzTV.Application/Channels/Commands/CreateChannel.cs
+++ b/ErsatzTV.Application/Channels/Commands/CreateChannel.cs
@@ -12,6 +12,7 @@ public record CreateChannel(
string Logo,
string PreferredAudioLanguageCode,
string PreferredAudioTitle,
+ ChannelProgressMode ProgressMode,
StreamingMode StreamingMode,
int? WatermarkId,
int? FallbackFillerId,
diff --git a/ErsatzTV.Application/Channels/Commands/CreateChannelHandler.cs b/ErsatzTV.Application/Channels/Commands/CreateChannelHandler.cs
index 72f48314..0ad8c330 100644
--- a/ErsatzTV.Application/Channels/Commands/CreateChannelHandler.cs
+++ b/ErsatzTV.Application/Channels/Commands/CreateChannelHandler.cs
@@ -73,6 +73,7 @@ public class CreateChannelHandler(
Group = request.Group,
Categories = request.Categories,
FFmpegProfileId = ffmpegProfileId,
+ ProgressMode = request.ProgressMode,
StreamingMode = request.StreamingMode,
Artwork = artwork,
PreferredAudioLanguageCode = preferredAudioLanguageCode,
diff --git a/ErsatzTV.Application/Channels/Commands/UpdateChannel.cs b/ErsatzTV.Application/Channels/Commands/UpdateChannel.cs
index 96667106..3857e693 100644
--- a/ErsatzTV.Application/Channels/Commands/UpdateChannel.cs
+++ b/ErsatzTV.Application/Channels/Commands/UpdateChannel.cs
@@ -13,6 +13,7 @@ public record UpdateChannel(
string Logo,
string PreferredAudioLanguageCode,
string PreferredAudioTitle,
+ ChannelProgressMode ProgressMode,
StreamingMode StreamingMode,
int? WatermarkId,
int? FallbackFillerId,
diff --git a/ErsatzTV.Application/Channels/Commands/UpdateChannelHandler.cs b/ErsatzTV.Application/Channels/Commands/UpdateChannelHandler.cs
index b0ca4ec0..e7005b5e 100644
--- a/ErsatzTV.Application/Channels/Commands/UpdateChannelHandler.cs
+++ b/ErsatzTV.Application/Channels/Commands/UpdateChannelHandler.cs
@@ -67,6 +67,7 @@ public class UpdateChannelHandler(
});
}
+ c.ProgressMode = update.ProgressMode;
c.StreamingMode = update.StreamingMode;
c.WatermarkId = update.WatermarkId;
c.FallbackFillerId = update.FallbackFillerId;
diff --git a/ErsatzTV.Application/Channels/Mapper.cs b/ErsatzTV.Application/Channels/Mapper.cs
index 8ec03bd6..0ac3ff3b 100644
--- a/ErsatzTV.Application/Channels/Mapper.cs
+++ b/ErsatzTV.Application/Channels/Mapper.cs
@@ -16,6 +16,7 @@ internal static class Mapper
GetLogo(channel),
channel.PreferredAudioLanguageCode,
channel.PreferredAudioTitle,
+ channel.ProgressMode,
channel.StreamingMode,
channel.WatermarkId,
channel.FallbackFillerId,
diff --git a/ErsatzTV.Application/ErsatzTV.Application.csproj b/ErsatzTV.Application/ErsatzTV.Application.csproj
index 48709b16..58f05440 100644
--- a/ErsatzTV.Application/ErsatzTV.Application.csproj
+++ b/ErsatzTV.Application/ErsatzTV.Application.csproj
@@ -12,7 +12,7 @@
-
+
@@ -20,8 +20,8 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
+
+
diff --git a/ErsatzTV.Application/Playouts/Commands/CreateFloodPlayoutHandler.cs b/ErsatzTV.Application/Playouts/Commands/CreateFloodPlayoutHandler.cs
index ad7f44aa..ca8e2a34 100644
--- a/ErsatzTV.Application/Playouts/Commands/CreateFloodPlayoutHandler.cs
+++ b/ErsatzTV.Application/Playouts/Commands/CreateFloodPlayoutHandler.cs
@@ -37,6 +37,10 @@ public class CreateFloodPlayoutHandler : IRequestHandler>, IBackgroundServiceRequest;
diff --git a/ErsatzTV.Application/Playouts/Commands/TimeShiftOnDemandPlayoutHandler.cs b/ErsatzTV.Application/Playouts/Commands/TimeShiftOnDemandPlayoutHandler.cs
new file mode 100644
index 00000000..041b2988
--- /dev/null
+++ b/ErsatzTV.Application/Playouts/Commands/TimeShiftOnDemandPlayoutHandler.cs
@@ -0,0 +1,41 @@
+using ErsatzTV.Core;
+using ErsatzTV.Core.Domain;
+using ErsatzTV.Core.Interfaces.Scheduling;
+using ErsatzTV.Infrastructure.Data;
+using ErsatzTV.Infrastructure.Extensions;
+using Microsoft.EntityFrameworkCore;
+
+namespace ErsatzTV.Application.Playouts;
+
+public class TimeShiftOnDemandPlayoutHandler(
+ IPlayoutTimeShifter playoutTimeShifter,
+ IDbContextFactory dbContextFactory)
+ : IRequestHandler>
+{
+ public async Task