Stream custom live channels using your own media
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

90 lines
2.6 KiB

using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.FFmpeg;
using ErsatzTV.Core.Interfaces.Scheduling;
using Microsoft.Extensions.Logging;
namespace ErsatzTV.Core.Scheduling;
public class PlayoutTimeShifter(IFFmpegSegmenterService segmenterService, ILogger<PlayoutTimeShifter> logger)
: IPlayoutTimeShifter
{
public void TimeShift(Playout playout, DateTimeOffset now, bool force)
{
if (playout.Channel.ProgressMode is not ChannelProgressMode.OnDemand)
{
return;
}
if (!force && segmenterService.IsActive(playout.Channel.Number))
{
logger.LogDebug(
"Will not time shift on demand playout that is active for channel {Number} - {Name}",
playout.Channel.Number,
playout.Channel.Name);
return;
}
if (playout.Items.Count == 0)
{
logger.LogDebug(
"Unable to time shift empty playout for channel {Number} - {Name}",
playout.Channel.Number,
playout.Channel.Name);
return;
}
if (playout.OnDemandCheckpoint is null)
{
logger.LogDebug(
"Time shifting unwatched playout for channel {Number} - {Name}",
playout.Channel.Number,
playout.Channel.Name);
playout.OnDemandCheckpoint = playout.Items.Min(p => p.StartOffset);
}
TimeSpan toOffset = now - playout.OnDemandCheckpoint.IfNone(now);
logger.LogDebug(
"Time shifting playout for channel {Number} - {Name} forward by {Time}",
playout.Channel.Number,
playout.Channel.Name,
toOffset);
// time shift items
foreach (PlayoutItem playoutItem in playout.Items)
{
playoutItem.Start += toOffset;
playoutItem.Finish += toOffset;
if (playoutItem.GuideStart.HasValue)
{
playoutItem.GuideStart += toOffset;
}
if (playoutItem.GuideFinish.HasValue)
{
playoutItem.GuideFinish += toOffset;
}
}
// time shift anchors
foreach (PlayoutProgramScheduleAnchor anchor in playout.ProgramScheduleAnchors)
{
if (anchor.AnchorDate.HasValue)
{
anchor.AnchorDate += toOffset;
}
}
// time shift anchor
if (playout.Anchor is not null)
{
playout.Anchor.NextStart += toOffset;
}
playout.OnDemandCheckpoint = now;
}
}