Files
ersatztv/ErsatzTV.Application/Playouts/Commands/UpdateOnDemandCheckpointHandler.cs
T
Jason DoveandGitHub a8b658a5ea add "on demand" channel progress mode (#1790)
* update dependencies

* add channel progress mode

* implement on demand channel progress

* update changelog
2024-07-16 12:21:52 -05:00

63 lines
2.3 KiB
C#

using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Repositories;
using ErsatzTV.Infrastructure.Data;
using ErsatzTV.Infrastructure.Extensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace ErsatzTV.Application.Playouts;
public class UpdateOnDemandCheckpointHandler(
IDbContextFactory<TvContext> dbContextFactory,
IConfigElementRepository configElementRepository,
ILogger<UpdateOnDemandCheckpointHandler> logger)
: IRequestHandler<UpdateOnDemandCheckpoint>
{
public async Task Handle(UpdateOnDemandCheckpoint request, CancellationToken cancellationToken)
{
await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
Option<Playout> maybePlayout = await dbContext.Playouts
.Include(p => p.Channel)
.Include(p => p.Items)
.SelectOneAsync(p => p.Channel.Number, p => p.Channel.Number == request.ChannelNumber);
foreach (Playout playout in maybePlayout)
{
if (playout.Channel.ProgressMode is not ChannelProgressMode.OnDemand)
{
return;
}
int timeout = await (await configElementRepository.GetValue<int>(ConfigElementKey.FFmpegSegmenterTimeout))
.IfNoneAsync(60);
// don't move checkpoint back in time
DateTimeOffset newCheckpoint = request.Checkpoint - TimeSpan.FromSeconds(timeout);
if (newCheckpoint > playout.OnDemandCheckpoint)
{
playout.OnDemandCheckpoint = newCheckpoint;
}
// don't checkpoint before the first item
// this could happen if you watch a new playout for less time than the segmenter timeout
if (playout.Items.Count > 0)
{
DateTimeOffset minStart = playout.Items.Min(p => p.StartOffset);
if (playout.OnDemandCheckpoint < minStart)
{
playout.OnDemandCheckpoint = minStart;
}
}
logger.LogDebug(
"Updating on demand checkpoint for channel {Number} - {Name} to {Checkpoint}",
playout.Channel.Number,
playout.Channel.Name,
playout.OnDemandCheckpoint);
await dbContext.SaveChangesAsync(cancellationToken);
}
}
}