@ -1,4 +1,5 @@
@@ -1,4 +1,5 @@
using System.Diagnostics ;
using System.Collections.Concurrent ;
using System.Diagnostics ;
using System.Diagnostics.CodeAnalysis ;
using System.Globalization ;
using System.IO.Pipelines ;
@ -48,6 +49,7 @@ public class HlsSessionWorker : IHlsSessionWorker
@@ -48,6 +49,7 @@ public class HlsSessionWorker : IHlsSessionWorker
private Timer _ timer ;
private DateTimeOffset _ transcodedUntil ;
private string _ workingDirectory ;
private ConcurrentDictionary < string , DateTimeOffset > _ initTouches = new ( ) ;
public HlsSessionWorker (
IServiceScopeFactory serviceScopeFactory ,
@ -89,7 +91,7 @@ public class HlsSessionWorker : IHlsSessionWorker
@@ -89,7 +91,7 @@ public class HlsSessionWorker : IHlsSessionWorker
}
}
public void Touch ( )
public void Touch ( Option < string > fileName )
{
lock ( _ sync )
{
@ -97,6 +99,12 @@ public class HlsSessionWorker : IHlsSessionWorker
@@ -97,6 +99,12 @@ public class HlsSessionWorker : IHlsSessionWorker
_l astAccess = DateTimeOffset . Now ;
foreach ( string init in fileName . Where ( f = > f . Contains ( "init.mp4" ) ) )
{
//_logger.LogDebug("Keep alive init {Init} for channel {ChannelNumber}", init, _channelNumber);
_ initTouches . AddOrUpdate ( init , DateTimeOffset . Now , ( _ , _ ) = > DateTimeOffset . Now ) ;
}
_ timer ? . Stop ( ) ;
_ timer ? . Start ( ) ;
}
@ -195,7 +203,7 @@ public class HlsSessionWorker : IHlsSessionWorker
@@ -195,7 +203,7 @@ public class HlsSessionWorker : IHlsSessionWorker
_l ogger . LogError ( "Transcode folder is NOT empty!" ) ;
}
Touch ( ) ;
Touch ( Option < string > . None ) ;
_ transcodedUntil = DateTimeOffset . Now ;
PlaylistStart = _ transcodedUntil ;
_ channelStart = _ transcodedUntil ;
@ -661,6 +669,8 @@ public class HlsSessionWorker : IHlsSessionWorker
@@ -661,6 +669,8 @@ public class HlsSessionWorker : IHlsSessionWorker
private void DeleteOldSegments ( TrimPlaylistResult trimResult )
{
var generatedAtHash = new System . Collections . Generic . HashSet < long > ( ) ;
// delete old segments
var allSegments = Directory . GetFiles ( _ workingDirectory , "live*.ts" )
. Append ( Directory . GetFiles ( _ workingDirectory , "live*.mp4" ) )
@ -677,6 +687,7 @@ public class HlsSessionWorker : IHlsSessionWorker
@@ -677,6 +687,7 @@ public class HlsSessionWorker : IHlsSessionWorker
{
generatedAt = 0 ;
}
generatedAtHash . Add ( generatedAt ) ;
return new Segment ( file , sequenceNumber , generatedAt ) ;
} )
. ToList ( ) ;
@ -685,7 +696,8 @@ public class HlsSessionWorker : IHlsSessionWorker
@@ -685,7 +696,8 @@ public class HlsSessionWorker : IHlsSessionWorker
. Map ( file = >
{
string fileName = Path . GetFileName ( file ) ;
return long . TryParse ( fileName . Split ( '_' ) [ 0 ] , out long generatedAt )
// only consider deleting inits that have no segments left on disk
return long . TryParse ( fileName . Split ( '_' ) [ 0 ] , out long generatedAt ) & & ! generatedAtHash . Contains ( generatedAt )
? new Segment ( file , 0 , generatedAt )
: Option < Segment > . None ;
} )
@ -702,15 +714,20 @@ public class HlsSessionWorker : IHlsSessionWorker
@@ -702,15 +714,20 @@ public class HlsSessionWorker : IHlsSessionWorker
// trimResult.Sequence);
}
if ( allInits . Count > 0 & & allSegments . Count > 0 )
DateTimeOffset toKeep = DateTimeOffset . Now . AddMinutes ( - 1 0 ) ;
foreach ( var init in allInits )
{
long minKeep = allSegments . Except ( toDelete ) . Map ( s = > s . GeneratedAt ) . Min ( ) ;
Option < Segment > maybeMinKeepInit =
allInits . OrderByDescending ( i = > i . GeneratedAt ) . Find ( i = > i . GeneratedAt < = minKeep ) ;
foreach ( var minKeepInit in maybeMinKeepInit )
string fileName = Path . GetFileName ( init . File ) ? ? string . Empty ;
if ( ! _ initTouches . TryGetValue ( fileName , out DateTimeOffset touchedAt ) )
{
continue ;
}
if ( touchedAt < toKeep )
{
// _logger.LogDebug("Deleting HLS inits less than {GeneratedAt}", minKeepInit.GeneratedAt);
toDelete . AddRange ( allInits . Where ( i = > i . GeneratedAt < minKeepInit . GeneratedAt ) ) ;
toDelete . Add ( init ) ;
_ initTouches . TryRemove ( fileName , out _ ) ;
}
}