lampac/Tracks/Engine/TranscodingJob.cs
lampac-talks f843f04fd4 chore: initial commit 154.3
Signed-off-by: lampac-talks <lampac-talks@users.noreply.github.com>
2026-01-30 16:23:09 +03:00

125 lines
3.2 KiB
C#

using Shared.Models.AppConf;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
namespace Tracks.Engine
{
internal sealed class TranscodingJob : IDisposable
{
private const int MaxLogLines = 200;
private readonly LinkedList<string> _log = new();
private readonly object _logSync = new();
private readonly CancellationTokenSource _cts = new();
private int _lastSegmentIndex = -1;
public TranscodingJob(string id, string streamId, string outputDirectory, Process process, TranscodingStartContext context)
{
Id = id;
StreamId = streamId;
OutputDirectory = outputDirectory;
Process = process;
Context = context;
StartedUtc = DateTime.UtcNow;
LastAccessUtc = StartedUtc;
}
public string Id { get; }
public string StreamId { get; }
public string OutputDirectory { get; }
public Process Process { get; }
public TranscodingStartContext Context { get; }
public DateTime StartedUtc { get; }
public DateTime LastAccessUtc { get; private set; }
public int? ExitCode { get; private set; }
public bool HasExited => Process.HasExited;
public CancellationToken CancellationToken => _cts.Token;
public void UpdateLastAccess() => LastAccessUtc = DateTime.UtcNow;
public int LastSegmentIndex => Volatile.Read(ref _lastSegmentIndex);
public void UpdateLastSegmentIndex(int segmentIndex)
{
if (segmentIndex < 0)
return;
while (true)
{
var current = Volatile.Read(ref _lastSegmentIndex);
if (segmentIndex <= current)
return;
if (Interlocked.CompareExchange(ref _lastSegmentIndex, segmentIndex, current) == current)
return;
}
}
public void AppendLog(string line)
{
if (string.IsNullOrWhiteSpace(line))
return;
lock (_logSync)
{
foreach (var part in line.Split('\n'))
{
string trimmed = part.TrimEnd('\r');
if (string.IsNullOrWhiteSpace(trimmed))
continue;
if (trimmed.Length > 2000)
trimmed = trimmed[..2000];
_log.AddLast(trimmed);
if (_log.Count > MaxLogLines)
_log.RemoveFirst();
}
}
}
public string[] SnapshotLog()
{
lock (_logSync)
return _log.ToArray();
}
public void SignalExit()
{
if (Process.HasExited)
ExitCode = Process.ExitCode;
}
public void StopBackground()
=> _cts.Cancel();
public void Dispose()
{
try
{
StopBackground();
}
catch { }
try
{
Process.Dispose();
}
catch { }
}
}
}