Browse Source

add mpeg-ts output format for hls direct (#1310)

pull/1311/head
Jason Dove 2 years ago committed by GitHub
parent
commit
6985826072
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      CHANGELOG.md
  2. 2
      ErsatzTV.Application/FFmpegProfiles/Queries/GetFFmpegSettingsHandler.cs
  3. 30
      ErsatzTV.Core/FFmpeg/FFmpegLibraryProcessService.cs
  4. 4
      ErsatzTV.FFmpeg.Tests/PipelineBuilderBaseTests.cs
  5. 2
      ErsatzTV.FFmpeg/Option/Mp4OutputOptions.cs
  6. 1
      ErsatzTV/Pages/Settings.razor

4
CHANGELOG.md

@ -17,6 +17,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). @@ -17,6 +17,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Skip checking for subtitles to extract when subtitles are not enabled on a channel/schedule item
### Changed
- `HLS Direct` streaming mode
- Use `MPEG-TS` container/output format by default to maintain v0.7.8 compatibility
- `MP4` and `MKV` container/output format can still be configured in `Settings`
- Improve `MP4` compatibility with certain content
- For `Pad` and `Duration` filler - prioritize filling the configured pad/duration
- This will skip filler that is too long in an attempt to avoid unscheduled time
- You may see the same filler more often, which means you may want to add more filler to your library so ETV has more options

2
ErsatzTV.Application/FFmpegProfiles/Queries/GetFFmpegSettingsHandler.cs

@ -46,7 +46,7 @@ public class GetFFmpegSettingsHandler : IRequestHandler<GetFFmpegSettings, FFmpe @@ -46,7 +46,7 @@ public class GetFFmpegSettingsHandler : IRequestHandler<GetFFmpegSettings, FFmpe
HlsSegmenterIdleTimeout = await hlsSegmenterIdleTimeout.IfNoneAsync(60),
WorkAheadSegmenterLimit = await workAheadSegmenterLimit.IfNoneAsync(1),
InitialSegmentCount = await initialSegmentCount.IfNoneAsync(1),
HlsDirectOutputFormat = await outputFormatKind.IfNoneAsync(OutputFormatKind.Mp4)
HlsDirectOutputFormat = await outputFormatKind.IfNoneAsync(OutputFormatKind.MpegTs)
};
foreach (int watermarkId in watermark)

30
ErsatzTV.Core/FFmpeg/FFmpegLibraryProcessService.cs

@ -199,21 +199,25 @@ public class FFmpegLibraryProcessService : IFFmpegProcessService @@ -199,21 +199,25 @@ public class FFmpegLibraryProcessService : IFFmpegProcessService
});
OutputFormatKind outputFormat = OutputFormatKind.MpegTs;
if (channel.StreamingMode == StreamingMode.HttpLiveStreamingSegmenter)
switch (channel.StreamingMode)
{
outputFormat = OutputFormatKind.Hls;
}
else if (channel.StreamingMode == StreamingMode.HttpLiveStreamingDirect)
{
// use mp4 by default
outputFormat = OutputFormatKind.Mp4;
// override with setting if applicable
Option<OutputFormatKind> maybeOutputFormat = await _configElementRepository
.GetValue<OutputFormatKind>(ConfigElementKey.FFmpegHlsDirectOutputFormat);
foreach (OutputFormatKind of in maybeOutputFormat)
case StreamingMode.HttpLiveStreamingSegmenter:
outputFormat = OutputFormatKind.Hls;
break;
case StreamingMode.HttpLiveStreamingDirect:
{
outputFormat = of;
// use mpeg-ts by default
outputFormat = OutputFormatKind.MpegTs;
// override with setting if applicable
Option<OutputFormatKind> maybeOutputFormat = await _configElementRepository
.GetValue<OutputFormatKind>(ConfigElementKey.FFmpegHlsDirectOutputFormat);
foreach (OutputFormatKind of in maybeOutputFormat)
{
outputFormat = of;
}
break;
}
}

4
ErsatzTV.FFmpeg.Tests/PipelineBuilderBaseTests.cs

@ -340,7 +340,7 @@ public class PipelineBuilderBaseTests @@ -340,7 +340,7 @@ public class PipelineBuilderBaseTests
// 0.4.0 reference: "-nostdin -threads 1 -hide_banner -loglevel error -nostats -fflags +genpts+discardcorrupt+igndts -re -ss 00:14:33.6195516 -i /tmp/whatever.mkv -map 0:0 -map 0:a -c:v copy -flags cgop -sc_threshold 0 -c:a copy -movflags +faststart -muxdelay 0 -muxpreload 0 -metadata service_provider="ErsatzTV" -metadata service_name="ErsatzTV" -t 00:06:39.6934484 -f mpegts -mpegts_flags +initial_discontinuity pipe:1"
command.Should().Be(
"-nostdin -hide_banner -nostats -loglevel error -fflags +genpts+discardcorrupt+igndts -re -i /tmp/whatever.mkv -map 0:1 -map 0:0 -muxdelay 0 -muxpreload 0 -movflags +faststart+frag_keyframe+delay_moov -flags cgop -sc_threshold 0 -c:v copy -c:a copy -f mp4 pipe:1");
"-nostdin -hide_banner -nostats -loglevel error -fflags +genpts+discardcorrupt+igndts -re -i /tmp/whatever.mkv -map 0:1 -map 0:0 -muxdelay 0 -muxpreload 0 -movflags +faststart+frag_keyframe+separate_moof+omit_tfhd_offset+empty_moov+delay_moov -flags cgop -sc_threshold 0 -c:v copy -c:a copy -f mp4 pipe:1");
}
[Test]
@ -420,7 +420,7 @@ public class PipelineBuilderBaseTests @@ -420,7 +420,7 @@ public class PipelineBuilderBaseTests
string command = PrintCommand(videoInputFile, audioInputFile, None, None, result);
command.Should().Be(
"-nostdin -hide_banner -nostats -loglevel error -fflags +genpts+discardcorrupt+igndts -re -i /tmp/whatever.mkv -map 0:a -map 0:0 -muxdelay 0 -muxpreload 0 -movflags +faststart+frag_keyframe+delay_moov -flags cgop -sc_threshold 0 -c:v copy -c:a copy -f mp4 pipe:1");
"-nostdin -hide_banner -nostats -loglevel error -fflags +genpts+discardcorrupt+igndts -re -i /tmp/whatever.mkv -map 0:a -map 0:0 -muxdelay 0 -muxpreload 0 -movflags +faststart+frag_keyframe+separate_moof+omit_tfhd_offset+empty_moov+delay_moov -flags cgop -sc_threshold 0 -c:v copy -c:a copy -f mp4 pipe:1");
}
[Test]

2
ErsatzTV.FFmpeg/Option/Mp4OutputOptions.cs

@ -2,5 +2,5 @@ @@ -2,5 +2,5 @@
public class Mp4OutputOptions : OutputOption
{
public override IList<string> OutputOptions => new List<string> { "-movflags", "+faststart+frag_keyframe+delay_moov" };
public override IList<string> OutputOptions => new List<string> { "-movflags", "+faststart+frag_keyframe+separate_moof+omit_tfhd_offset+empty_moov+delay_moov" };
}

1
ErsatzTV/Pages/Settings.razor

@ -100,6 +100,7 @@ @@ -100,6 +100,7 @@
Label="HLS Direct Output Format"
@bind-Value="_ffmpegSettings.HlsDirectOutputFormat"
For="@(() => _ffmpegSettings.HlsDirectOutputFormat)">
<MudSelectItem T="OutputFormatKind" Value="@OutputFormatKind.MpegTs">MPEG-TS</MudSelectItem>
<MudSelectItem T="OutputFormatKind" Value="@OutputFormatKind.Mp4">MP4</MudSelectItem>
<MudSelectItem T="OutputFormatKind" Value="@OutputFormatKind.Mkv">MKV</MudSelectItem>
</MudSelect>

Loading…
Cancel
Save