feat(console): add --list-sources diagnostic flag
Some checks failed
CI / build-and-test (push) Failing after 27s

Enumerates every raw NDI source string visible to the local NDI finder for ~5 seconds and prints unique ones, then exits. Bypasses NdiSourceParser so it surfaces sources that the parser would otherwise reject — useful for confirming the on-the-wire format Teams (or any other producer) is actually emitting on a given setup.

Used directly to diagnose the Teams 'MS Teams' vs. 'Teams' brand-prefix mismatch fixed in the previous commit; left in as a permanent debug tool for future setup issues.
This commit is contained in:
Zac Gaetano 2026-05-07 23:33:44 -04:00
parent ca124540a7
commit fa8d2a8fad

View file

@ -1,4 +1,5 @@
using System.Reactive.Linq;
using System.Runtime.Versioning;
using Microsoft.Extensions.Logging;
using TeamsISO.Engine.Controller;
using TeamsISO.Engine.Domain;
@ -22,12 +23,16 @@ using SysConsole = System.Console;
/// Usage:
/// teamsiso-console # discover only — print participants as they appear/leave
/// teamsiso-console --enable-all # auto-enable an ISO for every discovered participant
/// teamsiso-console --list-sources # diagnostic: print every raw NDI source string visible
/// on the network for ~5s, then exit. Useful for debugging
/// why expected Teams sources aren't being classified.
/// </summary>
public static class Program
{
public static async Task<int> Main(string[] args)
{
var enableAll = args.Contains("--enable-all", StringComparer.OrdinalIgnoreCase);
var listSources = args.Contains("--list-sources", StringComparer.OrdinalIgnoreCase);
using var loggerFactory = EngineLogging.CreateConsole(LogLevel.Information);
var logger = loggerFactory.CreateLogger("TeamsISO.Console");
@ -48,6 +53,11 @@ public static class Program
return 2;
}
if (listSources)
{
return await RunListSourcesAsync(interop, logger);
}
var configPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"TeamsISO", "config.json");
@ -125,4 +135,35 @@ public static class Program
logger.LogInformation("Engine stopped.");
return 0;
}
/// <summary>
/// Diagnostic mode: enumerates every raw NDI source string visible to the local
/// NDI finder for ~5 seconds, prints each unique one, then exits. Bypasses the
/// <see cref="Discovery.NdiSourceParser"/> entirely, so it surfaces sources that
/// the parser would otherwise reject — useful for confirming the on-the-wire
/// format Teams (or any other producer) is actually emitting.
/// </summary>
[SupportedOSPlatform("windows")]
private static async Task<int> RunListSourcesAsync(NdiInteropPInvoke interop, ILogger logger)
{
const int pollMs = 500;
const int totalMs = 5000;
logger.LogInformation("Listing raw NDI sources for {TotalMs} ms (polling every {PollMs} ms)…", totalMs, pollMs);
using var finder = interop.CreateFinder();
var seen = new SortedSet<string>(StringComparer.Ordinal);
var elapsed = 0;
while (elapsed < totalMs)
{
await Task.Delay(pollMs);
elapsed += pollMs;
foreach (var s in interop.GetCurrentSources(finder))
{
if (seen.Add(s))
logger.LogInformation(" + {Source}", s);
}
}
logger.LogInformation("Done. {Count} unique source(s) seen in {TotalMs} ms.", seen.Count, totalMs);
interop.Dispose();
return 0;
}
}