rename channel progress mode to playout mode (#2254)

This commit is contained in:
Jason Dove
2025-08-04 19:27:22 +00:00
committed by GitHub
parent a728c5e31e
commit b52159e8db
28 changed files with 12262 additions and 39 deletions

View File

@@ -65,6 +65,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Classic schedules: always schedule the full `Duration` amount instead of stopping mid-duration
- This allows duration items to be scheduled beyond midnight
- e.g. fixed start time 22:00 with 4 hour duration will schedule until 02:00 instead of stopping at midnight
- Rename channel setting `Progress Mode` to `Playout Mode`
- This controls the progression of the channel's playout, and has nothing to do with transcoding
- `Always` is now called `Continuous` (playout progresses with wall clock)
- `On Demand` is unchanged (playout only progresses while a client is watching the channel)
## [25.3.1] - 2025-07-24
### Fixed

View File

@@ -16,7 +16,7 @@ public record ChannelViewModel(
string StreamSelector,
string PreferredAudioLanguageCode,
string PreferredAudioTitle,
ChannelProgressMode ProgressMode,
ChannelPlayoutMode PlayoutMode,
StreamingMode StreamingMode,
int? WatermarkId,
int? FallbackFillerId,

View File

@@ -15,7 +15,7 @@ public record CreateChannel(
string StreamSelector,
string PreferredAudioLanguageCode,
string PreferredAudioTitle,
ChannelProgressMode ProgressMode,
ChannelPlayoutMode PlayoutMode,
StreamingMode StreamingMode,
int? WatermarkId,
int? FallbackFillerId,

View File

@@ -76,7 +76,7 @@ public class CreateChannelHandler(
Group = request.Group,
Categories = request.Categories,
FFmpegProfileId = ffmpegProfileId,
ProgressMode = request.ProgressMode,
PlayoutMode = request.PlayoutMode,
StreamingMode = request.StreamingMode,
Artwork = artwork,
StreamSelectorMode = request.StreamSelectorMode,

View File

@@ -16,7 +16,7 @@ public record UpdateChannel(
string StreamSelector,
string PreferredAudioLanguageCode,
string PreferredAudioTitle,
ChannelProgressMode ProgressMode,
ChannelPlayoutMode PlayoutMode,
StreamingMode StreamingMode,
int? WatermarkId,
int? FallbackFillerId,

View File

@@ -92,7 +92,7 @@ public class UpdateChannelHandler(
}
}
c.ProgressMode = update.ProgressMode;
c.PlayoutMode = update.PlayoutMode;
c.StreamingMode = update.StreamingMode;
c.WatermarkId = update.WatermarkId;
c.FallbackFillerId = update.FallbackFillerId;

View File

@@ -19,7 +19,7 @@ internal static class Mapper
channel.StreamSelector,
channel.PreferredAudioLanguageCode,
channel.PreferredAudioTitle,
channel.ProgressMode,
channel.PlayoutMode,
channel.StreamingMode,
channel.WatermarkId,
channel.FallbackFillerId,

View File

@@ -37,7 +37,7 @@ public class CreateFloodPlayoutHandler : IRequestHandler<CreateFloodPlayout, Eit
await dbContext.Playouts.AddAsync(playout);
await dbContext.SaveChangesAsync();
await _channel.WriteAsync(new BuildPlayout(playout.Id, PlayoutBuildMode.Reset));
if (playout.Channel.ProgressMode is ChannelProgressMode.OnDemand)
if (playout.Channel.PlayoutMode is ChannelPlayoutMode.OnDemand)
{
await _channel.WriteAsync(new TimeShiftOnDemandPlayout(playout.Channel.Number, DateTimeOffset.Now, false));
}

View File

@@ -49,7 +49,7 @@ public class
playout.ProgramSchedulePlayoutType,
playout.Channel.Name,
playout.Channel.Number,
playout.Channel.ProgressMode,
playout.Channel.PlayoutMode,
playout.ProgramSchedule?.Name ?? string.Empty,
playout.TemplateFile,
playout.ExternalJsonFile,

View File

@@ -24,7 +24,7 @@ public class UpdateOnDemandCheckpointHandler(
foreach (Playout playout in maybePlayout)
{
if (playout.Channel.ProgressMode is not ChannelProgressMode.OnDemand)
if (playout.Channel.PlayoutMode is not ChannelPlayoutMode.OnDemand)
{
return;
}

View File

@@ -41,7 +41,7 @@ public class UpdatePlayoutHandler : IRequestHandler<UpdatePlayout, Either<BaseEr
playout.ProgramSchedulePlayoutType,
playout.Channel.Name,
playout.Channel.Number,
playout.Channel.ProgressMode,
playout.Channel.PlayoutMode,
playout.ProgramSchedule?.Name ?? string.Empty,
playout.TemplateFile,
playout.ExternalJsonFile,

View File

@@ -49,7 +49,7 @@ public class
playout.ProgramSchedulePlayoutType,
playout.Channel.Name,
playout.Channel.Number,
playout.Channel.ProgressMode,
playout.Channel.PlayoutMode,
playout.ProgramSchedule?.Name ?? string.Empty,
playout.TemplateFile,
playout.ExternalJsonFile,

View File

@@ -7,7 +7,7 @@ public record PlayoutNameViewModel(
ProgramSchedulePlayoutType PlayoutType,
string ChannelName,
string ChannelNumber,
ChannelProgressMode ProgressMode,
ChannelPlayoutMode PlayoutMode,
string ScheduleName,
string TemplateFile,
string ExternalJsonFile,

View File

@@ -24,7 +24,7 @@ public class GetAllPlayoutsHandler : IRequestHandler<GetAllPlayouts, List<Playou
p.ProgramSchedulePlayoutType,
p.Channel.Name,
p.Channel.Number,
p.Channel.ProgressMode,
p.Channel.PlayoutMode,
p.ProgramScheduleId == null ? string.Empty : p.ProgramSchedule.Name,
p.TemplateFile,
p.ExternalJsonFile,

View File

@@ -22,7 +22,7 @@ public class GetPlayoutByIdHandler(IDbContextFactory<TvContext> dbContextFactory
p.ProgramSchedulePlayoutType,
p.Channel.Name,
p.Channel.Number,
p.Channel.ProgressMode,
p.Channel.PlayoutMode,
p.ProgramScheduleId == null ? string.Empty : p.ProgramSchedule.Name,
p.TemplateFile,
p.ExternalJsonFile,

View File

@@ -32,7 +32,7 @@ public class Channel
public ChannelMusicVideoCreditsMode MusicVideoCreditsMode { get; set; }
public string MusicVideoCreditsTemplate { get; set; }
public ChannelSongVideoMode SongVideoMode { get; set; }
public ChannelProgressMode ProgressMode { get; set; }
public ChannelPlayoutMode PlayoutMode { get; set; }
public ChannelActiveMode ActiveMode { get; set; }
public string WebEncodedName => WebUtility.UrlEncode(Name);
}

View File

@@ -1,7 +1,7 @@
namespace ErsatzTV.Core.Domain;
public enum ChannelProgressMode
public enum ChannelPlayoutMode
{
Always = 0,
Continuous = 0,
OnDemand = 1
}

View File

@@ -84,7 +84,7 @@ public class PlayoutBuilder : IPlayoutBuilder
// }
// time shift on demand channel if needed
if (playout.Channel.ProgressMode is ChannelProgressMode.OnDemand && mode is not PlayoutBuildMode.Reset)
if (playout.Channel.PlayoutMode is ChannelPlayoutMode.OnDemand && mode is not PlayoutBuildMode.Reset)
{
_playoutTimeShifter.TimeShift(playout, parameters.Start, false);
}
@@ -251,7 +251,7 @@ public class PlayoutBuilder : IPlayoutBuilder
playout.OnDemandCheckpoint = null;
// don't trim start for on demand channels, we want to time shift it all forward
if (playout.Channel.ProgressMode is ChannelProgressMode.OnDemand)
if (playout.Channel.PlayoutMode is ChannelPlayoutMode.OnDemand)
{
TrimStart = false;
}
@@ -265,7 +265,7 @@ public class PlayoutBuilder : IPlayoutBuilder
cancellationToken);
// time shift on demand channel if needed
if (playout.Channel.ProgressMode is ChannelProgressMode.OnDemand)
if (playout.Channel.PlayoutMode is ChannelPlayoutMode.OnDemand)
{
_playoutTimeShifter.TimeShift(playout, parameters.Start, false);
}
@@ -415,7 +415,7 @@ public class PlayoutBuilder : IPlayoutBuilder
}
// on demand channels end up with slightly more than expected due to time shifting from midnight to first build
if (playout.Channel.ProgressMode is not ChannelProgressMode.OnDemand)
if (playout.Channel.PlayoutMode is not ChannelPlayoutMode.OnDemand)
{
// check for future items that aren't grouped inside range
var futureItems = playout.Items.Filter(i => i.StartOffset > trimAfter).ToList();
@@ -457,7 +457,7 @@ public class PlayoutBuilder : IPlayoutBuilder
}
// on demand channels do NOT use alternate schedules
if (playout.Channel.ProgressMode is ChannelProgressMode.OnDemand)
if (playout.Channel.PlayoutMode is ChannelPlayoutMode.OnDemand)
{
activeSchedule = playout.ProgramSchedule;
}

View File

@@ -10,7 +10,7 @@ public class PlayoutTimeShifter(IFFmpegSegmenterService segmenterService, ILogge
{
public void TimeShift(Playout playout, DateTimeOffset now, bool force)
{
if (playout.Channel.ProgressMode is not ChannelProgressMode.OnDemand)
if (playout.Channel.PlayoutMode is not ChannelPlayoutMode.OnDemand)
{
return;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,28 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ErsatzTV.Infrastructure.MySql.Migrations
{
/// <inheritdoc />
public partial class Rename_ChannelProgressMode : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.RenameColumn(
name: "ProgressMode",
table: "Channel",
newName: "PlayoutMode");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.RenameColumn(
name: "PlayoutMode",
table: "Channel",
newName: "ProgressMode");
}
}
}

View File

@@ -284,6 +284,9 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
b.Property<string>("Number")
.HasColumnType("varchar(255)");
b.Property<int>("PlayoutMode")
.HasColumnType("int");
b.Property<string>("PreferredAudioLanguageCode")
.HasColumnType("longtext");
@@ -293,9 +296,6 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
b.Property<string>("PreferredSubtitleLanguageCode")
.HasColumnType("longtext");
b.Property<int>("ProgressMode")
.HasColumnType("int");
b.Property<int>("SongVideoMode")
.HasColumnType("int");

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,28 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ErsatzTV.Infrastructure.Sqlite.Migrations
{
/// <inheritdoc />
public partial class Rename_ChannelProgressMode : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.RenameColumn(
name: "ProgressMode",
table: "Channel",
newName: "PlayoutMode");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.RenameColumn(
name: "PlayoutMode",
table: "Channel",
newName: "ProgressMode");
}
}
}

View File

@@ -271,6 +271,9 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
b.Property<string>("Number")
.HasColumnType("TEXT");
b.Property<int>("PlayoutMode")
.HasColumnType("INTEGER");
b.Property<string>("PreferredAudioLanguageCode")
.HasColumnType("TEXT");
@@ -280,9 +283,6 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
b.Property<string>("PreferredSubtitleLanguageCode")
.HasColumnType("TEXT");
b.Property<int>("ProgressMode")
.HasColumnType("INTEGER");
b.Property<int>("SongVideoMode")
.HasColumnType("INTEGER");

View File

@@ -62,11 +62,11 @@
</MudStack>
<MudStack Row="true" Breakpoint="Breakpoint.SmAndDown" Class="form-field-stack gap-md-8 mb-5">
<div class="d-flex">
<MudText>Progress Mode</MudText>
<MudText>Playout Mode</MudText>
</div>
<MudSelect @bind-Value="_model.ProgressMode" For="@(() => _model.ProgressMode)">
<MudSelectItem Value="@(ChannelProgressMode.Always)">Always</MudSelectItem>
<MudSelectItem Value="@(ChannelProgressMode.OnDemand)">On Demand</MudSelectItem>
<MudSelect @bind-Value="_model.PlayoutMode" For="@(() => _model.PlayoutMode)" HelperText="Controls the progression of the channel's playout">
<MudSelectItem Value="@(ChannelPlayoutMode.Continuous)">Continuous</MudSelectItem>
<MudSelectItem Value="@(ChannelPlayoutMode.OnDemand)">On Demand</MudSelectItem>
</MudSelect>
</MudStack>
<MudStack Row="true" Breakpoint="Breakpoint.SmAndDown" Class="form-field-stack gap-md-8 mb-5">
@@ -310,7 +310,7 @@
_model.Logo = channelViewModel.Logo;
}
_model.ProgressMode = channelViewModel.ProgressMode;
_model.PlayoutMode = channelViewModel.PlayoutMode;
_model.StreamingMode = channelViewModel.StreamingMode;
_model.StreamSelectorMode = channelViewModel.StreamSelectorMode;
_model.StreamSelector = channelViewModel.StreamSelector;

View File

@@ -113,9 +113,9 @@
</div>
@if (context.PlayoutType == ProgramSchedulePlayoutType.Flood)
{
if (context.ProgressMode is ChannelProgressMode.OnDemand)
if (context.PlayoutMode is ChannelPlayoutMode.OnDemand)
{
<MudTooltip Text="Alternate Schedules are not supported with On Demand progress">
<MudTooltip Text="Alternate Schedules are not supported with On Demand playout mode">
<MudIconButton Icon="@Icons.Material.Filled.EditCalendar"
Disabled="true">
</MudIconButton>

View File

@@ -19,7 +19,7 @@ public class ChannelEditViewModel
public string PreferredAudioTitle { get; set; }
public ArtworkContentTypeModel Logo { get; set; }
public string ExternalLogoUrl { get; set; }
public ChannelProgressMode ProgressMode { get; set; }
public ChannelPlayoutMode PlayoutMode { get; set; }
public StreamingMode StreamingMode { get; set; }
public int? WatermarkId { get; set; }
public int? FallbackFillerId { get; set; }
@@ -53,7 +53,7 @@ public class ChannelEditViewModel
StreamSelector,
PreferredAudioLanguageCode,
PreferredAudioTitle,
ProgressMode,
PlayoutMode,
StreamingMode,
WatermarkId,
FallbackFillerId,
@@ -78,7 +78,7 @@ public class ChannelEditViewModel
StreamSelector,
PreferredAudioLanguageCode,
PreferredAudioTitle,
ProgressMode,
PlayoutMode,
StreamingMode,
WatermarkId,
FallbackFillerId,