70 lines
2.6 KiB
C#
70 lines
2.6 KiB
C#
using TeamsISO.Engine.Domain;
|
|
|
|
namespace TeamsISO.Engine.Discovery;
|
|
|
|
/// <summary>
|
|
/// Parses NDI source strings emitted by Microsoft Teams.
|
|
///
|
|
/// Examples Teams emits:
|
|
/// "MACHINE (Teams - Display Name)"
|
|
/// "MACHINE (Teams)" — auto-mixed active speaker
|
|
/// "MACHINE (Teams Audio)" — audio-only mix
|
|
/// "MACHINE (Teams Screen Share)" — screen share
|
|
/// </summary>
|
|
public static class NdiSourceParser
|
|
{
|
|
public static NdiSource? Parse(string fullName)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(fullName))
|
|
return null;
|
|
|
|
// Find the last '(' so machine names can themselves contain parens.
|
|
var openParen = fullName.LastIndexOf('(');
|
|
if (openParen <= 0 || !fullName.EndsWith(')'))
|
|
{
|
|
// Try outer parens for cases like "MACHINE (Teams - Smith, Bob (PM))"
|
|
// by walking from the first '(' that opens a "Teams" inner.
|
|
var firstParen = fullName.IndexOf(" (Teams", StringComparison.Ordinal);
|
|
if (firstParen <= 0)
|
|
return null;
|
|
openParen = firstParen + 1;
|
|
if (!fullName.EndsWith(')'))
|
|
return null;
|
|
}
|
|
else
|
|
{
|
|
// Re-anchor to the first " (Teams" if present, so display names containing
|
|
// their own parens (e.g. "Smith, Bob (PM)") don't get truncated.
|
|
var firstParen = fullName.IndexOf(" (Teams", StringComparison.Ordinal);
|
|
if (firstParen > 0)
|
|
openParen = firstParen + 1;
|
|
}
|
|
|
|
var machine = fullName[..openParen].TrimEnd();
|
|
if (machine.Length == 0)
|
|
return null;
|
|
|
|
var inner = fullName.Substring(openParen + 1, fullName.Length - openParen - 2).Trim();
|
|
|
|
if (!inner.StartsWith("Teams", StringComparison.Ordinal))
|
|
return null;
|
|
|
|
if (inner == "Teams")
|
|
return new NdiSource(fullName, machine, NdiSourceKind.ActiveSpeaker, DisplayName: null);
|
|
if (inner == "Teams Audio")
|
|
return new NdiSource(fullName, machine, NdiSourceKind.Audio, DisplayName: null);
|
|
if (inner == "Teams Screen Share")
|
|
return new NdiSource(fullName, machine, NdiSourceKind.ScreenShare, DisplayName: null);
|
|
|
|
const string prefix = "Teams - ";
|
|
if (inner.StartsWith(prefix, StringComparison.Ordinal))
|
|
{
|
|
var display = inner[prefix.Length..].Trim();
|
|
if (display.Length == 0)
|
|
return null;
|
|
return new NdiSource(fullName, machine, NdiSourceKind.Participant, display);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|