@ -5,7 +5,6 @@ using System.Timers;
@@ -5,7 +5,6 @@ using System.Timers;
using Bugsnag ;
using CliWrap ;
using CliWrap.Buffered ;
using ErsatzTV.Application.Channels ;
using ErsatzTV.Core ;
using ErsatzTV.Core.Domain ;
using ErsatzTV.Core.FFmpeg ;
@ -22,10 +21,13 @@ public class HlsSessionWorker : IHlsSessionWorker
@@ -22,10 +21,13 @@ public class HlsSessionWorker : IHlsSessionWorker
{
private static readonly SemaphoreSlim Slim = new ( 1 , 1 ) ;
private static int _ workAheadCount ;
private readonly IMediator _ mediator ;
private readonly IClient _ client ;
private readonly IHlsPlaylistFilter _ hlsPlaylistFilter ;
private readonly IConfigElementRepository _ configElementRepository ;
private readonly ILocalFileSystem _l ocalFileSystem ;
private readonly ILogger < HlsSessionWorker > _l ogger ;
private readonly IServiceScopeFactory _ serviceScopeFactory ;
private readonly Option < int > _ targetFramerate ;
private readonly object _ sync = new ( ) ;
private string _ channelNumber ;
private bool _d isposedValue ;
@ -33,20 +35,27 @@ public class HlsSessionWorker : IHlsSessionWorker
@@ -33,20 +35,27 @@ public class HlsSessionWorker : IHlsSessionWorker
private DateTimeOffset _l astAccess ;
private DateTimeOffset _l astDelete = DateTimeOffset . MinValue ;
private HlsSessionState _ state ;
private Option < int > _ targetFramerate ;
private Timer _ timer ;
private DateTimeOffset _ transcodedUntil ;
private IServiceScope _ serviceScope ;
public HlsSessionWorker (
IHlsPlaylistFilter hlsPlaylistFilter ,
IServiceScopeFactory serviceScopeFactory ,
IClient client ,
IHlsPlaylistFilter hlsPlaylistFilter ,
IConfigElementRepository configElementRepository ,
ILocalFileSystem localFileSystem ,
ILogger < HlsSessionWorker > logger )
ILogger < HlsSessionWorker > logger ,
Option < int > targetFramerate )
{
_ serviceScope = serviceScopeFactory . CreateScope ( ) ;
_ mediator = _ serviceScope . ServiceProvider . GetRequiredService < IMediator > ( ) ;
_ client = client ;
_ hlsPlaylistFilter = hlsPlaylistFilter ;
_ serviceScopeFactory = serviceScopeFactory ;
_ configElementRepository = configElementReposi tory;
_l ocalFileSystem = localFileSystem ;
_l ogger = logger ;
_ targetFramerate = targetFramerate ;
}
public DateTimeOffset PlaylistStart { get ; private set ; }
@ -133,17 +142,11 @@ public class HlsSessionWorker : IHlsSessionWorker
@@ -133,17 +142,11 @@ public class HlsSessionWorker : IHlsSessionWorker
_l ogger . LogInformation ( "Starting HLS session for channel {Channel}" , channelNumber ) ;
using IServiceScope scope = _ serviceScopeFactory . CreateScope ( ) ;
IMediator mediator = scope . ServiceProvider . GetRequiredService < IMediator > ( ) ;
ILocalFileSystem localFileSystem = scope . ServiceProvider . GetRequiredService < ILocalFileSystem > ( ) ;
if ( localFileSystem . ListFiles ( Path . Combine ( FileSystemLayout . TranscodeFolder , _ channelNumber ) ) . Any ( ) )
if ( _l ocalFileSystem . ListFiles ( Path . Combine ( FileSystemLayout . TranscodeFolder , _ channelNumber ) ) . Any ( ) )
{
_l ogger . LogError ( "Transcode folder is NOT empty!" ) ;
}
_ targetFramerate = await mediator . Send (
new GetChannelFramerate ( channelNumber ) ,
cancellationToken ) ;
Touch ( ) ;
_ transcodedUntil = DateTimeOffset . Now ;
@ -210,6 +213,10 @@ public class HlsSessionWorker : IHlsSessionWorker
@@ -210,6 +213,10 @@ public class HlsSessionWorker : IHlsSessionWorker
if ( disposing )
{
_ timer . Dispose ( ) ;
_ timer = null ;
_ serviceScope . Dispose ( ) ;
_ serviceScope = null ;
}
_d isposedValue = true ;
@ -256,8 +263,6 @@ public class HlsSessionWorker : IHlsSessionWorker
@@ -256,8 +263,6 @@ public class HlsSessionWorker : IHlsSessionWorker
bool realtime ,
CancellationToken cancellationToken )
{
using IServiceScope scope = _ serviceScopeFactory . CreateScope ( ) ;
try
{
if ( ! realtime )
@ -289,9 +294,7 @@ public class HlsSessionWorker : IHlsSessionWorker
@@ -289,9 +294,7 @@ public class HlsSessionWorker : IHlsSessionWorker
}
}
IMediator mediator = scope . ServiceProvider . GetRequiredService < IMediator > ( ) ;
long ptsOffset = await GetPtsOffset ( mediator , _ channelNumber , cancellationToken ) ;
long ptsOffset = await GetPtsOffset ( _ channelNumber , cancellationToken ) ;
// _logger.LogInformation("PTS offset: {PtsOffset}", ptsOffset);
_l ogger . LogInformation ( "HLS session state: {State}" , _ state ) ;
@ -312,7 +315,7 @@ public class HlsSessionWorker : IHlsSessionWorker
@@ -312,7 +315,7 @@ public class HlsSessionWorker : IHlsSessionWorker
// _logger.LogInformation("Request {@Request}", request);
Either < BaseError , PlayoutItemProcessModel > result = await mediator . Send ( request , cancellationToken ) ;
Either < BaseError , PlayoutItemProcessModel > result = await _ mediator . Send ( request , cancellationToken ) ;
// _logger.LogInformation("Result {Result}", result.ToString());
@ -365,7 +368,7 @@ public class HlsSessionWorker : IHlsSessionWorker
@@ -365,7 +368,7 @@ public class HlsSessionWorker : IHlsSessionWorker
commandResult . ExitCode ,
commandResult . StandardError ) ;
Either < BaseError , PlayoutItemProcessModel > maybeOfflineProcess = await mediator . Send (
Either < BaseError , PlayoutItemProcessModel > maybeOfflineProcess = await _ mediator . Send (
new GetErrorProcess (
_ channelNumber ,
"segmenter" ,
@ -414,8 +417,7 @@ public class HlsSessionWorker : IHlsSessionWorker
@@ -414,8 +417,7 @@ public class HlsSessionWorker : IHlsSessionWorker
try
{
IClient client = scope . ServiceProvider . GetRequiredService < IClient > ( ) ;
client . Notify ( ex ) ;
_ client . Notify ( ex ) ;
}
catch ( Exception )
{
@ -494,10 +496,7 @@ public class HlsSessionWorker : IHlsSessionWorker
@@ -494,10 +496,7 @@ public class HlsSessionWorker : IHlsSessionWorker
}
}
private async Task < long > GetPtsOffset (
IMediator mediator ,
string channelNumber ,
CancellationToken cancellationToken )
private async Task < long > GetPtsOffset ( string channelNumber , CancellationToken cancellationToken )
{
await Slim . WaitAsync ( cancellationToken ) ;
try
@ -510,7 +509,7 @@ public class HlsSessionWorker : IHlsSessionWorker
@@ -510,7 +509,7 @@ public class HlsSessionWorker : IHlsSessionWorker
return result ;
}
Either < BaseError , PtsAndDuration > queryResult = await mediator . Send (
Either < BaseError , PtsAndDuration > queryResult = await _ mediator . Send (
new GetLastPtsDuration ( channelNumber ) ,
cancellationToken ) ;
@ -534,9 +533,7 @@ public class HlsSessionWorker : IHlsSessionWorker
@@ -534,9 +533,7 @@ public class HlsSessionWorker : IHlsSessionWorker
private async Task < int > GetWorkAheadLimit ( )
{
using IServiceScope scope = _ serviceScopeFactory . CreateScope ( ) ;
IConfigElementRepository repo = scope . ServiceProvider . GetRequiredService < IConfigElementRepository > ( ) ;
return await repo . GetValue < int > ( ConfigElementKey . FFmpegWorkAheadSegmenters )
return await _ configElementRepository . GetValue < int > ( ConfigElementKey . FFmpegWorkAheadSegmenters )
. Map ( maybeCount = > maybeCount . Match ( identity , ( ) = > 1 ) ) ;
}