consolidate streaming modes (#2544)
* consolidate segmenters * let old segmenter mode query params continue to work
This commit is contained in:
@@ -119,7 +119,7 @@ public class TroubleshootController(
|
||||
|
||||
string[] segmentFiles = streamingMode switch
|
||||
{
|
||||
StreamingMode.HttpLiveStreamingSegmenterFmp4 => Directory.GetFiles(
|
||||
StreamingMode.HttpLiveStreamingSegmenter => Directory.GetFiles(
|
||||
FileSystemLayout.TranscodeTroubleshootingFolder,
|
||||
"*.m4s"),
|
||||
_ => Directory.GetFiles(FileSystemLayout.TranscodeTroubleshootingFolder, "*.ts")
|
||||
|
||||
@@ -10,7 +10,6 @@ using ErsatzTV.Application.Subtitles.Queries;
|
||||
using ErsatzTV.Core;
|
||||
using ErsatzTV.Core.Domain;
|
||||
using ErsatzTV.Core.FFmpeg;
|
||||
using ErsatzTV.Core.Interfaces.FFmpeg;
|
||||
using ErsatzTV.Core.Interfaces.Streaming;
|
||||
using ErsatzTV.Extensions;
|
||||
using Flurl;
|
||||
@@ -23,18 +22,15 @@ namespace ErsatzTV.Controllers;
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public class InternalController : StreamingControllerBase
|
||||
{
|
||||
private readonly IFFmpegSegmenterService _ffmpegSegmenterService;
|
||||
private readonly ILogger<InternalController> _logger;
|
||||
private readonly IMediator _mediator;
|
||||
|
||||
public InternalController(
|
||||
IFFmpegSegmenterService ffmpegSegmenterService,
|
||||
IGraphicsEngine graphicsEngine,
|
||||
IMediator mediator,
|
||||
ILogger<InternalController> logger)
|
||||
: base(graphicsEngine, logger)
|
||||
{
|
||||
_ffmpegSegmenterService = ffmpegSegmenterService;
|
||||
_mediator = mediator;
|
||||
_logger = logger;
|
||||
}
|
||||
@@ -46,19 +42,7 @@ public class InternalController : StreamingControllerBase
|
||||
.ToActionResult();
|
||||
|
||||
[HttpGet("ffmpeg/stream/{channelNumber}")]
|
||||
public async Task<IActionResult> GetStream(
|
||||
string channelNumber,
|
||||
[FromQuery]
|
||||
string mode = "mixed")
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case "segmenter-v2":
|
||||
return await GetSegmenterV2Stream(channelNumber);
|
||||
default:
|
||||
return await GetTsLegacyStream(channelNumber);
|
||||
}
|
||||
}
|
||||
public Task<IActionResult> GetStream(string channelNumber) => GetTsLegacyStream(channelNumber);
|
||||
|
||||
[HttpGet("ffmpeg/remote-stream/{remoteStreamId}")]
|
||||
public async Task<IActionResult> GetRemoteStream(int remoteStreamId, CancellationToken cancellationToken)
|
||||
@@ -262,19 +246,6 @@ public class InternalController : StreamingControllerBase
|
||||
return new NotFoundResult();
|
||||
}
|
||||
|
||||
private async Task<IActionResult> GetSegmenterV2Stream(string channelNumber)
|
||||
{
|
||||
if (_ffmpegSegmenterService.TryGetWorker(channelNumber, out IHlsSessionWorker worker) &&
|
||||
worker is HlsSessionWorkerV2 v2)
|
||||
{
|
||||
Either<BaseError, PlayoutItemProcessModel> result = await v2.GetNextPlayoutItemProcess();
|
||||
return GetProcessResponse(result, channelNumber, StreamingMode.HttpLiveStreamingSegmenterV2);
|
||||
}
|
||||
|
||||
_logger.LogWarning("Unable to locate session worker for channel {Channel}", channelNumber);
|
||||
return new NotFoundResult();
|
||||
}
|
||||
|
||||
private async Task<IActionResult> GetTsLegacyStream(string channelNumber)
|
||||
{
|
||||
var request = new GetPlayoutItemProcessByChannelNumber(
|
||||
|
||||
@@ -208,12 +208,6 @@ public class IptvController : StreamingControllerBase
|
||||
case StreamingMode.HttpLiveStreamingSegmenter:
|
||||
mode = "segmenter";
|
||||
break;
|
||||
case StreamingMode.HttpLiveStreamingSegmenterFmp4:
|
||||
mode = "segmenter-fmp4";
|
||||
break;
|
||||
case StreamingMode.HttpLiveStreamingSegmenterV2:
|
||||
mode = "segmenter-v2";
|
||||
break;
|
||||
default:
|
||||
return Redirect($"~/iptv/channel/{channelNumber}.ts{AccessTokenQuery()}");
|
||||
}
|
||||
@@ -223,15 +217,15 @@ public class IptvController : StreamingControllerBase
|
||||
switch (mode)
|
||||
{
|
||||
case "segmenter":
|
||||
case "segmenter-fmp4":
|
||||
case "segmenter-v2":
|
||||
case "segmenter-fmp4":
|
||||
_logger.LogDebug(
|
||||
"Maybe starting ffmpeg session for channel {Channel}, mode {Mode}",
|
||||
channelNumber,
|
||||
mode);
|
||||
var request = new StartFFmpegSession(channelNumber, mode, Request.Scheme, Request.Host.ToString());
|
||||
Either<BaseError, Unit> result = await _mediator.Send(request);
|
||||
string multiVariantPlaylist = await GetMultiVariantPlaylist(channelNumber, mode);
|
||||
string multiVariantPlaylist = await GetMultiVariantPlaylist(channelNumber);
|
||||
return result.Match<IActionResult>(
|
||||
_ =>
|
||||
{
|
||||
@@ -291,37 +285,10 @@ public class IptvController : StreamingControllerBase
|
||||
public async Task<IActionResult> GetStream(string channelNumber) =>
|
||||
await GetHlsDirectStream(channelNumber);
|
||||
|
||||
private async Task<string> GetMultiVariantPlaylist(string channelNumber, string mode)
|
||||
private async Task<string> GetMultiVariantPlaylist(string channelNumber)
|
||||
{
|
||||
string file = mode switch
|
||||
{
|
||||
// this serves the unmodified playlist from disk
|
||||
"segmenter-v2" => "live.m3u8",
|
||||
|
||||
_ => "hls.m3u8"
|
||||
};
|
||||
|
||||
var variantPlaylist =
|
||||
$"{Request.Scheme}://{Request.Host}/iptv/session/{channelNumber}/{file}{AccessTokenQuery()}";
|
||||
|
||||
try
|
||||
{
|
||||
if (mode == "segmenter-v2")
|
||||
{
|
||||
string fileName = Path.Combine(FileSystemLayout.TranscodeFolder, channelNumber, "playlist.m3u8");
|
||||
if (System.IO.File.Exists(fileName))
|
||||
{
|
||||
string text = await System.IO.File.ReadAllTextAsync(fileName, Encoding.UTF8);
|
||||
return text.Replace("live.m3u8", variantPlaylist);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(
|
||||
ex,
|
||||
"Failed to return ffmpeg multi-variant playlist; falling back to generated playlist");
|
||||
}
|
||||
$"{Request.Scheme}://{Request.Host}/iptv/session/{channelNumber}/hls.m3u8{AccessTokenQuery()}";
|
||||
|
||||
Option<ChannelStreamingSpecsViewModel> maybeStreamingSpecs =
|
||||
await _mediator.Send(new GetChannelStreamingSpecs(channelNumber));
|
||||
|
||||
@@ -77,13 +77,7 @@ public abstract class StreamingControllerBase(IGraphicsEngine graphicsEngine, IL
|
||||
pipe.Writer,
|
||||
TaskScheduler.Default);
|
||||
|
||||
string contentType = mode switch
|
||||
{
|
||||
StreamingMode.HttpLiveStreamingSegmenterV2 => "video/x-matroska",
|
||||
_ => "video/mp2t"
|
||||
};
|
||||
|
||||
return new FileStreamResult(pipe.Reader.AsStream(), contentType);
|
||||
return new FileStreamResult(pipe.Reader.AsStream(), "video/mp2t");
|
||||
}
|
||||
|
||||
// this will never happen
|
||||
|
||||
Reference in New Issue
Block a user