wait for two initial segments in playback troubleshooting (#2532)
This commit is contained in:
@@ -33,6 +33,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||||||
- Dramatically improve stream startup time
|
- Dramatically improve stream startup time
|
||||||
- VAAPI: fix scaling image-based subtitles (e.g. dvdsub)
|
- VAAPI: fix scaling image-based subtitles (e.g. dvdsub)
|
||||||
- Fix HLS Segmenter (fmp4) on Windows
|
- Fix HLS Segmenter (fmp4) on Windows
|
||||||
|
- Playback troubleshooting: wait for at least 2 initial segments (up to configured initial segment count) to reduce stalls
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Do not use graphics engine for single, permanent watermark
|
- Do not use graphics engine for single, permanent watermark
|
||||||
|
|||||||
@@ -430,7 +430,6 @@ public class GetPlayoutItemProcessByChannelNumberHandler : FFmpegProcessHandler<
|
|||||||
: StreamInputKind.Vod,
|
: StreamInputKind.Vod,
|
||||||
playoutItemWithPath.PlayoutItem.FillerKind,
|
playoutItemWithPath.PlayoutItem.FillerKind,
|
||||||
inPoint,
|
inPoint,
|
||||||
outPoint,
|
|
||||||
request.ChannelStartTime,
|
request.ChannelStartTime,
|
||||||
request.PtsOffset,
|
request.PtsOffset,
|
||||||
request.TargetFramerate,
|
request.TargetFramerate,
|
||||||
|
|||||||
@@ -246,7 +246,6 @@ public class PrepareTroubleshootingPlaybackHandler(
|
|||||||
mediaItem is RemoteStream { IsLive: true } ? StreamInputKind.Live : StreamInputKind.Vod,
|
mediaItem is RemoteStream { IsLive: true } ? StreamInputKind.Live : StreamInputKind.Vod,
|
||||||
FillerKind.None,
|
FillerKind.None,
|
||||||
inPoint,
|
inPoint,
|
||||||
outPoint,
|
|
||||||
channelStartTime: DateTimeOffset.Now,
|
channelStartTime: DateTimeOffset.Now,
|
||||||
0,
|
0,
|
||||||
None,
|
None,
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -50,7 +49,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -75,7 +73,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -96,7 +93,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -117,7 +113,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -138,7 +133,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -161,7 +155,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -184,7 +177,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -205,7 +197,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -228,7 +219,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
now,
|
now,
|
||||||
now.AddMinutes(5),
|
now.AddMinutes(5),
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -252,7 +242,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
now,
|
now,
|
||||||
now.AddMinutes(5),
|
now.AddMinutes(5),
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -280,7 +269,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -307,7 +295,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -334,7 +321,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -362,7 +348,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -389,7 +374,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -419,7 +403,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -450,7 +433,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -480,7 +462,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -510,7 +491,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -540,7 +520,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -572,7 +551,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -603,7 +581,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -634,7 +611,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -664,7 +640,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -695,7 +670,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -725,7 +699,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -756,7 +729,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -782,7 +754,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -806,7 +777,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -830,7 +800,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -855,7 +824,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -880,7 +848,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -905,7 +872,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -930,7 +896,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -954,7 +919,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -978,7 +942,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -987,7 +950,7 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Should_SetAudioDuration_With_CorrectFormat_ForTransportStream()
|
public void Should_SetPadAudio_ForTransportStream()
|
||||||
{
|
{
|
||||||
FFmpegProfile ffmpegProfile = TestProfile() with
|
FFmpegProfile ffmpegProfile = TestProfile() with
|
||||||
{
|
{
|
||||||
@@ -1008,12 +971,11 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.FromMinutes(2),
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
|
|
||||||
actual.AudioDuration.IfNone(TimeSpan.MinValue).ShouldBe(TimeSpan.FromMinutes(2));
|
actual.PadAudio.ShouldBe(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -1032,7 +994,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
@@ -1058,7 +1019,6 @@ public class FFmpegPlaybackSettingsCalculatorTests
|
|||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
None);
|
None);
|
||||||
|
|||||||
@@ -81,7 +81,6 @@ public class FFmpegLibraryProcessService : IFFmpegProcessService
|
|||||||
StreamInputKind streamInputKind,
|
StreamInputKind streamInputKind,
|
||||||
FillerKind fillerKind,
|
FillerKind fillerKind,
|
||||||
TimeSpan inPoint,
|
TimeSpan inPoint,
|
||||||
TimeSpan outPoint,
|
|
||||||
DateTimeOffset channelStartTime,
|
DateTimeOffset channelStartTime,
|
||||||
long ptsOffset,
|
long ptsOffset,
|
||||||
Option<int> targetFramerate,
|
Option<int> targetFramerate,
|
||||||
@@ -102,7 +101,6 @@ public class FFmpegLibraryProcessService : IFFmpegProcessService
|
|||||||
start,
|
start,
|
||||||
now,
|
now,
|
||||||
inPoint,
|
inPoint,
|
||||||
outPoint,
|
|
||||||
hlsRealtime,
|
hlsRealtime,
|
||||||
streamInputKind,
|
streamInputKind,
|
||||||
targetFramerate);
|
targetFramerate);
|
||||||
@@ -184,7 +182,7 @@ public class FFmpegLibraryProcessService : IFFmpegProcessService
|
|||||||
playbackSettings.AudioBitrate,
|
playbackSettings.AudioBitrate,
|
||||||
playbackSettings.AudioBufferSize,
|
playbackSettings.AudioBufferSize,
|
||||||
playbackSettings.AudioSampleRate,
|
playbackSettings.AudioSampleRate,
|
||||||
videoPath == audioPath ? playbackSettings.AudioDuration : Option<TimeSpan>.None,
|
videoPath == audioPath,
|
||||||
playbackSettings.NormalizeLoudnessMode switch
|
playbackSettings.NormalizeLoudnessMode switch
|
||||||
{
|
{
|
||||||
NormalizeLoudnessMode.LoudNorm => AudioFilter.LoudNorm,
|
NormalizeLoudnessMode.LoudNorm => AudioFilter.LoudNorm,
|
||||||
@@ -239,7 +237,7 @@ public class FFmpegLibraryProcessService : IFFmpegProcessService
|
|||||||
// when no audio streams are available, use null audio source
|
// when no audio streams are available, use null audio source
|
||||||
if (!audioVersion.MediaVersion.Streams.Any(s => s.MediaStreamKind is MediaStreamKind.Audio))
|
if (!audioVersion.MediaVersion.Streams.Any(s => s.MediaStreamKind is MediaStreamKind.Audio))
|
||||||
{
|
{
|
||||||
audioInputFile = new NullAudioInputFile(audioState with { AudioDuration = playbackSettings.AudioDuration });
|
audioInputFile = new NullAudioInputFile(audioState with { PadAudio = playbackSettings.PadAudio });
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputFormatKind outputFormat = OutputFormatKind.MpegTs;
|
OutputFormatKind outputFormat = OutputFormatKind.MpegTs;
|
||||||
@@ -599,7 +597,7 @@ public class FFmpegLibraryProcessService : IFFmpegProcessService
|
|||||||
playbackSettings.AudioBitrate,
|
playbackSettings.AudioBitrate,
|
||||||
playbackSettings.AudioBufferSize,
|
playbackSettings.AudioBufferSize,
|
||||||
playbackSettings.AudioSampleRate,
|
playbackSettings.AudioSampleRate,
|
||||||
Option<TimeSpan>.None,
|
false,
|
||||||
AudioFilter.None);
|
AudioFilter.None);
|
||||||
|
|
||||||
string videoFormat = GetVideoFormat(playbackSettings);
|
string videoFormat = GetVideoFormat(playbackSettings);
|
||||||
@@ -789,7 +787,7 @@ public class FFmpegLibraryProcessService : IFFmpegProcessService
|
|||||||
channel.FFmpegProfile,
|
channel.FFmpegProfile,
|
||||||
Option<int>.None);
|
Option<int>.None);
|
||||||
|
|
||||||
playbackSettings.AudioDuration = Option<TimeSpan>.None;
|
playbackSettings.PadAudio = false;
|
||||||
|
|
||||||
string audioFormat = playbackSettings.AudioFormat switch
|
string audioFormat = playbackSettings.AudioFormat switch
|
||||||
{
|
{
|
||||||
@@ -805,7 +803,7 @@ public class FFmpegLibraryProcessService : IFFmpegProcessService
|
|||||||
playbackSettings.AudioBitrate,
|
playbackSettings.AudioBitrate,
|
||||||
playbackSettings.AudioBufferSize,
|
playbackSettings.AudioBufferSize,
|
||||||
playbackSettings.AudioSampleRate,
|
playbackSettings.AudioSampleRate,
|
||||||
Option<TimeSpan>.None,
|
false,
|
||||||
playbackSettings.NormalizeLoudnessMode switch
|
playbackSettings.NormalizeLoudnessMode switch
|
||||||
{
|
{
|
||||||
// TODO: NormalizeLoudnessMode.LoudNorm => AudioFilter.LoudNorm,
|
// TODO: NormalizeLoudnessMode.LoudNorm => AudioFilter.LoudNorm,
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public class FFmpegPlaybackSettings
|
|||||||
public Option<int> AudioBufferSize { get; set; }
|
public Option<int> AudioBufferSize { get; set; }
|
||||||
public Option<int> AudioChannels { get; set; }
|
public Option<int> AudioChannels { get; set; }
|
||||||
public Option<int> AudioSampleRate { get; set; }
|
public Option<int> AudioSampleRate { get; set; }
|
||||||
public Option<TimeSpan> AudioDuration { get; set; }
|
public bool PadAudio { get; set; }
|
||||||
public FFmpegProfileAudioFormat AudioFormat { get; set; }
|
public FFmpegProfileAudioFormat AudioFormat { get; set; }
|
||||||
public bool Deinterlace { get; set; }
|
public bool Deinterlace { get; set; }
|
||||||
public Option<int> VideoTrackTimeScale { get; set; }
|
public Option<int> VideoTrackTimeScale { get; set; }
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ public static class FFmpegPlaybackSettingsCalculator
|
|||||||
DateTimeOffset start,
|
DateTimeOffset start,
|
||||||
DateTimeOffset now,
|
DateTimeOffset now,
|
||||||
TimeSpan inPoint,
|
TimeSpan inPoint,
|
||||||
TimeSpan outPoint,
|
|
||||||
bool hlsRealtime,
|
bool hlsRealtime,
|
||||||
StreamInputKind streamInputKind,
|
StreamInputKind streamInputKind,
|
||||||
Option<int> targetFramerate)
|
Option<int> targetFramerate)
|
||||||
@@ -168,7 +167,7 @@ public static class FFmpegPlaybackSettingsCalculator
|
|||||||
result.AudioBufferSize = ffmpegProfile.AudioBufferSize;
|
result.AudioBufferSize = ffmpegProfile.AudioBufferSize;
|
||||||
result.AudioChannels = ffmpegProfile.AudioChannels;
|
result.AudioChannels = ffmpegProfile.AudioChannels;
|
||||||
result.AudioSampleRate = ffmpegProfile.AudioSampleRate;
|
result.AudioSampleRate = ffmpegProfile.AudioSampleRate;
|
||||||
result.AudioDuration = outPoint - inPoint;
|
result.PadAudio = true;
|
||||||
result.NormalizeLoudnessMode = ffmpegProfile.NormalizeLoudnessMode;
|
result.NormalizeLoudnessMode = ffmpegProfile.NormalizeLoudnessMode;
|
||||||
|
|
||||||
result.Deinterlace = ffmpegProfile.DeinterlaceVideo == true &&
|
result.Deinterlace = ffmpegProfile.DeinterlaceVideo == true &&
|
||||||
|
|||||||
@@ -84,7 +84,6 @@ public class FFmpegProcessService
|
|||||||
DateTimeOffset.UnixEpoch,
|
DateTimeOffset.UnixEpoch,
|
||||||
DateTimeOffset.UnixEpoch,
|
DateTimeOffset.UnixEpoch,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.Zero,
|
|
||||||
false,
|
false,
|
||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
Option<int>.None);
|
Option<int>.None);
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ public interface IFFmpegProcessService
|
|||||||
StreamInputKind streamInputKind,
|
StreamInputKind streamInputKind,
|
||||||
FillerKind fillerKind,
|
FillerKind fillerKind,
|
||||||
TimeSpan inPoint,
|
TimeSpan inPoint,
|
||||||
TimeSpan outPoint,
|
|
||||||
DateTimeOffset channelStartTime,
|
DateTimeOffset channelStartTime,
|
||||||
long ptsOffset,
|
long ptsOffset,
|
||||||
Option<int> targetFramerate,
|
Option<int> targetFramerate,
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class PipelineBuilderBaseTests
|
|||||||
320,
|
320,
|
||||||
640,
|
640,
|
||||||
48,
|
48,
|
||||||
Option<TimeSpan>.None,
|
false,
|
||||||
AudioFilter.None));
|
AudioFilter.None));
|
||||||
|
|
||||||
var desiredState = new FrameState(
|
var desiredState = new FrameState(
|
||||||
@@ -151,7 +151,7 @@ public class PipelineBuilderBaseTests
|
|||||||
320,
|
320,
|
||||||
640,
|
640,
|
||||||
48,
|
48,
|
||||||
Option<TimeSpan>.None,
|
false,
|
||||||
AudioFilter.None));
|
AudioFilter.None));
|
||||||
|
|
||||||
var desiredState = new FrameState(
|
var desiredState = new FrameState(
|
||||||
@@ -308,7 +308,7 @@ public class PipelineBuilderBaseTests
|
|||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
false,
|
||||||
AudioFilter.None));
|
AudioFilter.None));
|
||||||
|
|
||||||
var desiredState = new FrameState(
|
var desiredState = new FrameState(
|
||||||
|
|||||||
@@ -467,7 +467,7 @@ public abstract class PipelineBuilderBase : IPipelineBuilder
|
|||||||
audioInputFile.FilterSteps.Add(new AudioResampleFilter());
|
audioInputFile.FilterSteps.Add(new AudioResampleFilter());
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (TimeSpan _ in audioInputFile.DesiredState.AudioDuration)
|
if (audioInputFile.DesiredState.PadAudio)
|
||||||
{
|
{
|
||||||
audioInputFile.FilterSteps.Add(new AudioPadFilter());
|
audioInputFile.FilterSteps.Add(new AudioPadFilter());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ public record AudioState(
|
|||||||
Option<int> AudioBitrate,
|
Option<int> AudioBitrate,
|
||||||
Option<int> AudioBufferSize,
|
Option<int> AudioBufferSize,
|
||||||
Option<int> AudioSampleRate,
|
Option<int> AudioSampleRate,
|
||||||
Option<TimeSpan> AudioDuration,
|
bool PadAudio,
|
||||||
AudioFilter NormalizeLoudnessFilter)
|
AudioFilter NormalizeLoudnessFilter)
|
||||||
{
|
{
|
||||||
public static readonly AudioState Copy = new(
|
public static readonly AudioState Copy = new(
|
||||||
@@ -15,7 +15,7 @@ public record AudioState(
|
|||||||
Option<int>.None,
|
Option<int>.None,
|
||||||
Option<int>.None,
|
Option<int>.None,
|
||||||
Option<int>.None,
|
Option<int>.None,
|
||||||
Option<TimeSpan>.None,
|
false,
|
||||||
AudioFilter.None
|
AudioFilter.None
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -395,7 +395,6 @@ public class TranscodingTests
|
|||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
FillerKind.None,
|
FillerKind.None,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.FromSeconds(3),
|
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
0,
|
0,
|
||||||
None,
|
None,
|
||||||
@@ -707,7 +706,6 @@ public class TranscodingTests
|
|||||||
StreamInputKind.Vod,
|
StreamInputKind.Vod,
|
||||||
FillerKind.None,
|
FillerKind.None,
|
||||||
TimeSpan.Zero,
|
TimeSpan.Zero,
|
||||||
TimeSpan.FromSeconds(3),
|
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
0,
|
0,
|
||||||
None,
|
None,
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using ErsatzTV.Core;
|
|||||||
using ErsatzTV.Core.Domain;
|
using ErsatzTV.Core.Domain;
|
||||||
using ErsatzTV.Core.Interfaces.FFmpeg;
|
using ErsatzTV.Core.Interfaces.FFmpeg;
|
||||||
using ErsatzTV.Core.Interfaces.Metadata;
|
using ErsatzTV.Core.Interfaces.Metadata;
|
||||||
|
using ErsatzTV.Core.Interfaces.Repositories;
|
||||||
using ErsatzTV.Core.Interfaces.Troubleshooting;
|
using ErsatzTV.Core.Interfaces.Troubleshooting;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@@ -18,6 +19,7 @@ namespace ErsatzTV.Controllers.Api;
|
|||||||
public class TroubleshootController(
|
public class TroubleshootController(
|
||||||
ChannelWriter<IFFmpegWorkerRequest> channelWriter,
|
ChannelWriter<IFFmpegWorkerRequest> channelWriter,
|
||||||
ILocalFileSystem localFileSystem,
|
ILocalFileSystem localFileSystem,
|
||||||
|
IConfigElementRepository configElementRepository,
|
||||||
ITroubleshootingNotifier notifier,
|
ITroubleshootingNotifier notifier,
|
||||||
IMediator mediator) : ControllerBase
|
IMediator mediator) : ControllerBase
|
||||||
{
|
{
|
||||||
@@ -94,20 +96,41 @@ public class TroubleshootController(
|
|||||||
troubleshootingInfo),
|
troubleshootingInfo),
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
|
|
||||||
string playlistFile = Path.Combine(
|
string playlistFile = Path.Combine(FileSystemLayout.TranscodeTroubleshootingFolder, "live.m3u8");
|
||||||
FileSystemLayout.TranscodeFolder,
|
|
||||||
".troubleshooting",
|
|
||||||
"live.m3u8");
|
|
||||||
|
|
||||||
while (!localFileSystem.FileExists(playlistFile))
|
while (!localFileSystem.FileExists(playlistFile))
|
||||||
{
|
{
|
||||||
await Task.Delay(TimeSpan.FromMilliseconds(250), cancellationToken);
|
await Task.Delay(TimeSpan.FromMilliseconds(100), cancellationToken);
|
||||||
if (cancellationToken.IsCancellationRequested || notifier.IsFailed(sessionId))
|
if (cancellationToken.IsCancellationRequested || notifier.IsFailed(sessionId))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int initialSegmentCount = await configElementRepository
|
||||||
|
.GetValue<int>(ConfigElementKey.FFmpegInitialSegmentCount, cancellationToken)
|
||||||
|
.Map(maybeCount => maybeCount.Match(c => c, () => 1));
|
||||||
|
|
||||||
|
initialSegmentCount = Math.Max(initialSegmentCount, 2);
|
||||||
|
|
||||||
|
bool hasSegments = false;
|
||||||
|
while (!hasSegments)
|
||||||
|
{
|
||||||
|
await Task.Delay(TimeSpan.FromMilliseconds(100), cancellationToken);
|
||||||
|
|
||||||
|
string[] segmentFiles = streamingMode switch
|
||||||
|
{
|
||||||
|
StreamingMode.HttpLiveStreamingSegmenterFmp4 => Directory.GetFiles(
|
||||||
|
FileSystemLayout.TranscodeTroubleshootingFolder,
|
||||||
|
"*.m4s"),
|
||||||
|
_ => Directory.GetFiles(FileSystemLayout.TranscodeTroubleshootingFolder, "*.ts")
|
||||||
|
};
|
||||||
|
|
||||||
|
if (segmentFiles.Length >= initialSegmentCount)
|
||||||
|
{
|
||||||
|
hasSegments = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!notifier.IsFailed(sessionId))
|
if (!notifier.IsFailed(sessionId))
|
||||||
{
|
{
|
||||||
return Redirect("~/iptv/session/.troubleshooting/live.m3u8");
|
return Redirect("~/iptv/session/.troubleshooting/live.m3u8");
|
||||||
|
|||||||
Reference in New Issue
Block a user