Browse Source

improve stream startup (#2525)

pull/2526/head
Jason Dove 3 months ago committed by GitHub
parent
commit
ea5956a268
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 4
      ErsatzTV.Application/Streaming/HlsSessionWorker.cs
  3. 18
      ErsatzTV.Application/Streaming/Queries/GetPlayoutItemProcessByChannelNumberHandler.cs
  4. 31
      ErsatzTV.FFmpeg/Pipeline/PipelineBuilderBase.cs

1
CHANGELOG.md

@ -28,6 +28,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). @@ -28,6 +28,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Fix playback troubleshooting selecting a subtitle even with no subtitle stream selected in the UI
- Fix intermittent watermark opacity
- Improve reliability of live remote streams; they should transcode closer to realtime in most cases
- Dramatically improve stream startup time
### Changed
- Do not use graphics engine for single, permanent watermark

4
ErsatzTV.Application/Streaming/HlsSessionWorker.cs

@ -393,9 +393,7 @@ public class HlsSessionWorker : IHlsSessionWorker @@ -393,9 +393,7 @@ public class HlsSessionWorker : IHlsSessionWorker
return result;
}
private async Task<bool> Transcode(
bool realtime,
CancellationToken cancellationToken)
private async Task<bool> Transcode(bool realtime, CancellationToken cancellationToken)
{
try
{

18
ErsatzTV.Application/Streaming/Queries/GetPlayoutItemProcessByChannelNumberHandler.cs

@ -281,6 +281,22 @@ public class GetPlayoutItemProcessByChannelNumberHandler : FFmpegProcessHandler< @@ -281,6 +281,22 @@ public class GetPlayoutItemProcessByChannelNumberHandler : FFmpegProcessHandler<
DateTimeOffset effectiveNow = request.StartAtZero ? start : now;
TimeSpan duration = finish - effectiveNow;
bool isComplete = true;
// if we are working ahead, limit to 45s
if (!request.HlsRealtime)
{
TimeSpan limit = TimeSpan.FromSeconds(45);
if (duration > limit)
{
finish = effectiveNow + limit;
outPoint = inPoint + limit;
duration = limit;
isComplete = false;
}
}
if (_isDebugNoSync)
{
Command doesNotExistProcess = await _ffmpegProcessService.ForError(
@ -427,7 +443,7 @@ public class GetPlayoutItemProcessByChannelNumberHandler : FFmpegProcessHandler< @@ -427,7 +443,7 @@ public class GetPlayoutItemProcessByChannelNumberHandler : FFmpegProcessHandler<
playoutItemResult.GraphicsEngineContext,
duration,
finish,
true);
isComplete);
return Right<BaseError, PlayoutItemProcessModel>(result);
}

31
ErsatzTV.FFmpeg/Pipeline/PipelineBuilderBase.cs

@ -563,7 +563,7 @@ public abstract class PipelineBuilderBase : IPipelineBuilder @@ -563,7 +563,7 @@ public abstract class PipelineBuilderBase : IPipelineBuilder
: SetDecoder(videoInputFile, videoStream, ffmpegState, context);
//SetStillImageInfiniteLoop(videoInputFile, videoStream, ffmpegState);
SetRealtimeInput(videoInputFile, desiredState);
SetRealtimeInput(videoInputFile, ffmpegState, desiredState);
SetInfiniteLoop(videoInputFile, videoStream, ffmpegState, desiredState);
SetFrameRateOutput(desiredState, pipelineSteps);
SetVideoTrackTimescaleOutput(desiredState, pipelineSteps);
@ -760,29 +760,26 @@ public abstract class PipelineBuilderBase : IPipelineBuilder @@ -760,29 +760,26 @@ public abstract class PipelineBuilderBase : IPipelineBuilder
}
}
private void SetRealtimeInput(VideoInputFile videoInputFile, FrameState desiredState)
private void SetRealtimeInput(VideoInputFile videoInputFile, FFmpegState ffmpegState, FrameState desiredState)
{
if (videoInputFile.StreamInputKind is StreamInputKind.Live)
if (videoInputFile.StreamInputKind is StreamInputKind.Live || !desiredState.Realtime)
{
return;
}
int initialBurst;
if (!desiredState.Realtime)
{
initialBurst = 45;
}
else
AudioFilter filter = _audioInputFile
.Map(a => a.DesiredState.NormalizeLoudnessFilter)
.IfNone(AudioFilter.None);
int initialBurst = filter switch
{
AudioFilter filter = _audioInputFile
.Map(a => a.DesiredState.NormalizeLoudnessFilter)
.IfNone(AudioFilter.None);
AudioFilter.LoudNorm => 5,
_ => 0
};
initialBurst = filter switch
{
AudioFilter.LoudNorm => 5,
_ => 0
};
if (ffmpegState.Finish.Any(finish => finish.TotalSeconds < initialBurst))
{
return;
}
_audioInputFile.Iter(a => a.AddOption(new ReadrateInputOption(_ffmpegCapabilities, initialBurst, _logger)));

Loading…
Cancel
Save