feat(domain): add Participant, IsoAssignment, IsoOutput, IsoHealthStats, FrameProcessingSettings, EngineConfig, EngineAlert
Some checks failed
CI / build-and-test (push) Failing after 22s
Some checks failed
CI / build-and-test (push) Failing after 22s
This commit is contained in:
parent
aaf3184a8e
commit
464f559576
7 changed files with 105 additions and 0 deletions
19
src/TeamsISO.Engine/Domain/EngineAlert.cs
Normal file
19
src/TeamsISO.Engine/Domain/EngineAlert.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
namespace TeamsISO.Engine.Domain;
|
||||
|
||||
/// <summary>
|
||||
/// Structured engine alerts for UI banner display and ops logging.
|
||||
/// </summary>
|
||||
public abstract record EngineAlert(string Message)
|
||||
{
|
||||
public sealed record NdiRuntimeMismatch(string DetectedVersion, string ExpectedVersion)
|
||||
: EngineAlert($"NDI runtime version mismatch: detected {DetectedVersion}, expected {ExpectedVersion}.");
|
||||
|
||||
public sealed record OutputNameCollision(string Name)
|
||||
: EngineAlert($"Another TeamsISO instance on the LAN is emitting an output named '{Name}'.");
|
||||
|
||||
public sealed record PipelineError(Guid ParticipantId, string Reason)
|
||||
: EngineAlert($"Pipeline {ParticipantId} entered Error: {Reason}");
|
||||
|
||||
public sealed record ConfigSaveFailed(string Reason)
|
||||
: EngineAlert($"Failed to save configuration: {Reason}");
|
||||
}
|
||||
9
src/TeamsISO.Engine/Domain/EngineConfig.cs
Normal file
9
src/TeamsISO.Engine/Domain/EngineConfig.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
namespace TeamsISO.Engine.Domain;
|
||||
|
||||
public sealed record EngineConfig(
|
||||
FrameProcessingSettings Global,
|
||||
IReadOnlyList<IsoAssignment> Assignments)
|
||||
{
|
||||
public static readonly EngineConfig Default =
|
||||
new(FrameProcessingSettings.Default, Array.Empty<IsoAssignment>());
|
||||
}
|
||||
34
src/TeamsISO.Engine/Domain/FrameProcessingSettings.cs
Normal file
34
src/TeamsISO.Engine/Domain/FrameProcessingSettings.cs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
namespace TeamsISO.Engine.Domain;
|
||||
|
||||
public sealed record FrameProcessingSettings(
|
||||
TargetFramerate Framerate,
|
||||
TargetResolution Resolution,
|
||||
AspectMode Aspect,
|
||||
AudioMode Audio)
|
||||
{
|
||||
public static readonly FrameProcessingSettings Default =
|
||||
new(TargetFramerate.Fps30, TargetResolution.R1080p, AspectMode.Pillarbox, AudioMode.Auto);
|
||||
|
||||
/// <summary>Returns the framerate enum value as a numeric frames-per-second.</summary>
|
||||
public double FramerateHz => Framerate switch
|
||||
{
|
||||
TargetFramerate.Fps23_976 => 24000.0 / 1001.0,
|
||||
TargetFramerate.Fps24 => 24.0,
|
||||
TargetFramerate.Fps25 => 25.0,
|
||||
TargetFramerate.Fps29_97 => 30000.0 / 1001.0,
|
||||
TargetFramerate.Fps30 => 30.0,
|
||||
TargetFramerate.Fps50 => 50.0,
|
||||
TargetFramerate.Fps59_94 => 60000.0 / 1001.0,
|
||||
TargetFramerate.Fps60 => 60.0,
|
||||
_ => throw new InvalidOperationException($"Unknown framerate: {Framerate}")
|
||||
};
|
||||
|
||||
/// <summary>Returns the resolution as (width, height).</summary>
|
||||
public (int Width, int Height) ResolutionSize => Resolution switch
|
||||
{
|
||||
TargetResolution.R720p => (1280, 720),
|
||||
TargetResolution.R1080p => (1920, 1080),
|
||||
TargetResolution.R4K => (3840, 2160),
|
||||
_ => throw new InvalidOperationException($"Unknown resolution: {Resolution}")
|
||||
};
|
||||
}
|
||||
9
src/TeamsISO.Engine/Domain/IsoAssignment.cs
Normal file
9
src/TeamsISO.Engine/Domain/IsoAssignment.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
namespace TeamsISO.Engine.Domain;
|
||||
|
||||
/// <summary>
|
||||
/// Operator's intent for an ISO output. Persisted to <c>config.json</c>.
|
||||
/// </summary>
|
||||
public sealed record IsoAssignment(
|
||||
Guid ParticipantId,
|
||||
bool IsEnabled,
|
||||
string? CustomOutputName);
|
||||
15
src/TeamsISO.Engine/Domain/IsoHealthStats.cs
Normal file
15
src/TeamsISO.Engine/Domain/IsoHealthStats.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
namespace TeamsISO.Engine.Domain;
|
||||
|
||||
public sealed record IsoHealthStats(
|
||||
long FramesIn,
|
||||
long FramesOut,
|
||||
long FramesDropped,
|
||||
long FramesDuplicated,
|
||||
DateTimeOffset? LastFrameAt,
|
||||
double IncomingFps,
|
||||
int IncomingWidth,
|
||||
int IncomingHeight)
|
||||
{
|
||||
public static readonly IsoHealthStats Empty =
|
||||
new(0, 0, 0, 0, null, 0, 0, 0);
|
||||
}
|
||||
7
src/TeamsISO.Engine/Domain/IsoOutput.cs
Normal file
7
src/TeamsISO.Engine/Domain/IsoOutput.cs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
namespace TeamsISO.Engine.Domain;
|
||||
|
||||
public sealed record IsoOutput(
|
||||
Guid ParticipantId,
|
||||
string EffectiveOutputName,
|
||||
IsoHealthStats Stats,
|
||||
IsoState State);
|
||||
12
src/TeamsISO.Engine/Domain/Participant.cs
Normal file
12
src/TeamsISO.Engine/Domain/Participant.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
namespace TeamsISO.Engine.Domain;
|
||||
|
||||
/// <summary>
|
||||
/// Operator-facing identity for a single human in the meeting.
|
||||
/// <c>Id</c> is engine-assigned and stable across the rename heuristic.
|
||||
/// </summary>
|
||||
public sealed record Participant(
|
||||
Guid Id,
|
||||
string DisplayName,
|
||||
NdiSource? CurrentSource,
|
||||
DateTimeOffset FirstSeen,
|
||||
DateTimeOffset LastSeen);
|
||||
Loading…
Reference in a new issue