9.4 KiB
9.4 KiB
Changelog
All notable changes to TeamsISO are documented here. The format follows Keep a Changelog and this project adheres to Semantic Versioning.
Unreleased
Added — May 2026 feature batch
Engine
- NDI Groups: discovery + sender support so Teams' raw broadcasts can be pinned to a private "teamsiso-input" group while TeamsISO's own normalized outputs broadcast on Public.
- One-click "Apply transcoder topology" writes
ndi-config.v1.jsonso all Teams broadcasts go to the private group and TeamsISO re-emits on Public. RawBgraRecorderSinkper-output recorder:IRecorderSinkinterface + raw BGRA stream +manifest.json+convert.cmdscript for FFmpeg conversion to H.264 MKV.- Recording markers:
IRecorderSink.AddMarker(label)fan-out viaIIsoController.AddRecordingMarker. Markers land inmanifest.jsonundermarkers[]for post-production chaptering. - Preview thumbnails:
IsoPipeline.LatestProcessedFramepublished viaVolatile.Readso the UI can render 160×90 BGRA thumbnails in the participants DataGrid at 1Hz. - Idempotent
ParticipantTracker.HandleAdded: re-emitting Added for an already-live source refreshes LastSeen instead of duplicating the row. Fixes the "click Refresh and rows ghost-duplicate" bug introduced by the Refresh-Discovery affordance. IIsoController.RefreshDiscovery()rebuilds the NDI finder on the next poll tick — useful right after applying a new transcoder topology.IIsoController.AddRecordingMarker(label)fan-out to every active recorder.IIsoController.SetRecording(enabled, dir)global recording toggle; per-participant override viaEnableIsoAsync(...recordOverride...).
Host (WPF)
- Active Speaker as a synthetic routable participant with deterministic v5
GUID derived from
auto-mix:<machine>. - Auto-disable on departure: when a participant's NDI source disappears, optionally tear down their pipeline.
- Operator presets: chromeless
Presets…dialog with Save / Apply / Delete / Duplicate / Export / Import. Persisted at%LOCALAPPDATA%\TeamsISO\presets.json. Bundle formatteamsiso-presets-bundle/v1for migration between machines. - Auto-apply last preset on launch (configurable, off by default).
--apply-preset NAMECLI flag for desktop-shortcut workflows.PresetApplier— single source of truth for "apply preset to live participants" used by the dialog, REST surface, and auto-apply path.- Live preview thumbnails per participant (160×90 BGRA WriteableBitmap).
- Right-click context menu on participant rows: Toggle ISO, Record-this- participant, Copy NDI source name.
- Live filter input (substring match on display name).
- "Enable all online" + "Stop all ISOs" + "Refresh" header actions.
- Per-participant recording opt-out checkbox (Rec column).
- Custom NDI output name template with
{name}/{guid}/{machine}/{timestamp}tokens. - Phase E.1 — Launcher: rail "Launch / Stop Teams" toggle.
- Phase E.2 — Window orchestration: hide / show Teams windows from the rail.
- Phase E.3 — In-call controls (UIA): Mute, Camera, Share, Leave, Raise hand, plus PostMessage shortcut forwarding fallback. Candidate names localized for English / German / Spanish / French / Portuguese / Japanese.
- Crash diagnostics: AppDomain + Dispatcher + TaskScheduler unhandled exception handlers wired to Serilog.Critical + user-facing dialog.
- First-launch onboarding dialog with 5-step setup checklist.
- About dialog gained "Show welcome", "Check for updates", "Export diagnostics" buttons.
- Diagnostic bundle export: zips logs + config + presets + version metadata
into
~/Downloads/teamsiso-diagnostics-<ts>.zipfor bug reports. - Update check: manual via About + auto-on-launch banner (throttled to 24h,
opt-out via flag file at
%LOCALAPPDATA%\TeamsISO\no-update-check.flag). - Disk space watcher auto-disables recording at <1GB free.
- Settings panel refactored into OUTPUT / NETWORK / DISPLAY tabs.
- Reset-to-defaults button in OUTPUT tab.
- Enriched footer: REC badge, control-surface badge, session timer (HH:MM:SS since first ISO went live), dynamic status text ("3/5 ISOs live · 2 recording").
- Window-scoped keyboard shortcuts: F1 (help), Ctrl+M (marker), Ctrl+Shift+S (stop all), Ctrl+R (refresh discovery).
- F1 help / cheat-sheet dialog.
UIPreferencesstatic persistsHideLocalSelf,AutoDisableOnDeparture,ParticipantSort(JoinOrder / Alphabetical / OnlineFirst) across launches to%LOCALAPPDATA%\TeamsISO\ui-prefs.json.- Pop-out per-participant preview window (right-click → Open preview…) refreshes at ~20Hz and is multi-monitor friendly.
- Configurable participant sort order via the DISPLAY tab dropdown.
- Stop-All confirms before tearing down running pipelines (catches mid-show misclicks).
- About dialog gained "Logs / Recordings / Notes" folder shortcut buttons.
NotesWindowinline viewer for today's show-notes file with 2s polling.- Duplicate-preset action in the Presets dialog with smart
(copy N)name suggestions. --apply-preset NAMEcommand-line flag for desktop-shortcut workflows.- New
TeamsISO.App.Testsnet8.0-windows test project. Initial coverage:OperatorPresetStoreTests(round-trip, name collisions, schema, bundle import/export, garbage-file resilience),OutputNameTemplateTests(token expansion + sanitization),OscMessageTests(wire-format parsing of int/float/string/T/F type tags). Backed by anInternalsVisibleTogrant- a test-only
OperatorPresetStore.PathOverridehook.
- a test-only
IsoHealthStats.PeakAudioLevelfield + DataGrid VU-bar UI scaffolding. Engine still emits 0.0 (audio capture is a focused follow-up); the bar's decay logic is in place so it animates as soon as engine-side audio parsing lands.MediaFoundationRecorderSinkscaffold under#if MF_AVAILABLEfor inline H.264 encoding via Vortice.MediaFoundation. ~10× smaller files than the raw BGRA recorder. Activation steps documented atdocs/REAL-TIME-RECORDING.md.- System-tray icon + minimize-to-tray toggle. Adds
<UseWindowsForms>true</UseWindowsForms>forNotifyIcon; theTrayIconHostlives onApp(process lifetime, not main-window lifetime). Right-click menu has Show / Stop all ISOs / Exit. - Built-in NDI test pattern:
TeamsISO.Console --test-patternbroadcasts a synthetic 1280×720 30fps source namedTEAMSISO_TESTshowing SMPTE color bars + a moving sweep band. Verifies NDI runtime, sender configuration, and downstream discovery without needing Teams running. Backed byTestPatternGeneratorin the engine + 4 unit tests covering buffer size, alpha, color distinctness, and sweep animation. - Always-toast on participant disconnect, regardless of
AutoDisableOnDeparturesetting. Distinguishes "ISO torn down" (auto-disable on) from "ISO still running on slate" (auto-disable off) so operators don't miss a silent drop mid-show. - Restart this ISO right-click action — disable + brief delay + re-enable for one participant only. Useful when a single feed flakes without affecting other ISOs.
- Roll recording action: rolls every active recording into a new chunk
(disable + re-enable each pipeline; recorder finalizes its
manifest.jsonand starts a fresh subdirectory). Surfaced viaMainViewModel.RollRecordingCommand, RESTPOST /recording/roll, and OSC/teamsiso/recording/roll. Useful for chaptering between show segments.
Control surface
- REST API on
127.0.0.1:9755with endpoints for participant ISO toggle (by Id or display name), preset apply, refresh discovery, stop-all, recording on/off, marker drop, notes, and Teams in-call commands. Documented atdocs/CONTROL-SURFACE.md. - WebSocket
/wspushes live participant state at 4Hz with snapshot diffing. - OSC bridge on UDP
127.0.0.1:9000mirrors the REST vocabulary (/teamsiso/iso "Jane" 1,/teamsiso/preset "...", etc.). - Embedded HTML control panel at
GET /ui— phone-friendly remote with live state and one-click action buttons. - Show notes service:
POST /notesand/teamsiso/notes "..."append timestamped lines to%LOCALAPPDATA%\TeamsISO\Notes\<YYYY-MM-DD>.md.
CI / Release
- Forgejo CI is green; tag-push release workflow builds + tests + publishes
- builds MSI on a Windows runner and attaches it to the auto-created release via the REST API.
- Optional MSI + exe code-signing wired into
release.yml— gated onSIGN_CERT_PFX_BASE64+SIGN_CERT_PASSWORDForgejo Secrets.
Fixed
.slnfpath-separator mismatch (forward slashes for cross-platform).- NDI native DLL resolution via
NativeLibraryresolver. ExpectedRuntimeVersionPrefixupdated to NDI 6 banner format.NdiSourceParseraccepts current Teams desktop'sMS Teams - <name>brand format.- ActiveSpeaker source removal no longer poisons the rename-window heuristic for a Participant joining the same machine within the window.
IsoPipeline.Stateaccess synchronized viaVolatile.Read/Write.- REST handlers now correctly marshal
ObservableCollectionreads + writes through the UI dispatcher. - WebSocket upgrade no longer falls into
res.Close()finally block (was killing freshly-upgraded connections). ParticipantViewModel.UpdateThumbnaildefends against malformed frames (width*height*4 > Pixels.Length).HasThumbnailcorrectly firesPropertyChangedwhenThumbnailtransitions from null.