Single cipher suite (ECDHE-ECDSA-AES128-GCM-SHA256), client certificate
checked against the SDP fingerprint, extended master secret.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Building blocks for a minimal WebRTC stack on CryptoKit/CommonCrypto,
verified against RFC 5769, RFC 3711 and OpenSSL vectors.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
As a login item macOS launched Musubi without its window, so the SwiftUI
.task never ran: no outputs, no remote control after a reboot. An app
delegate now starts discovery and the coordinator in applicationDidFinishLaunching.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Right after launch macOS briefly reports 'Local network prohibited'; the
connection then stayed in waiting and was never retried. Connect attempts now
time out after 6 s and start over; the waiting reason is logged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The mode switch posts didChangeScreenParameters synchronously; reconcile ran
nested before the output was registered and opened a second window/receiver,
which stayed visible after stopping. Register first, never nest reconcile,
handle the notification asynchronously. Switching sources keeps the 50 Hz mode.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Coordinator: restores live state on launch, role-based Bonjour server/browser,
node adopts commands, control keeps desired config per node and re-sends on reconnect
- Scene menu (load, save, save as, export, import), settings (role, interface, login item)
- Remote screens with status on the control; node banner
- Developer ID signing with hardened runtime and audio-input entitlement
- Retry and clear message when macOS blocks Bonjour
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Scene = control config + config per node; screens matched by name, then position
- Remote module: length-prefixed JSON messages, NodeServer (Bonjour on the
technical interface), NodeBrowser with auto-reconnect
- ChannelSelection moves to MusubiCore
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- NDIReceiver captures audio (audio-only bandwidth for sound routes)
- AUHAL output per device, mic input via AUHAL, fan-out to routes
- Drift-compensated, allocation-free render path; backlog trimmed on start
- Global talk key (Ctrl-Option-Space, hold or toggle) gates mic routes
- Sound tab with channel strips, meters, gain, mute, L/R/L+R
- --audio-route launch argument, per-minute audio CSV, 10 s diagnostics log
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Senders like NDI Test Patterns send a still image once; a held NDI connection
now counts as alive so the receiver does not reconnect in a loop.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- NDIReceiver: per-source receive thread, IOSurface pixel buffers, watchdog reconnect
- VideoOutput: borderless output window above menu bar, AVSampleBufferVideoRenderer,
50 Hz display mode for app lifetime, display sleep assertion
- Screen cards with drag and drop, live fps and frame loss
- Per-minute stats CSV in ~/Library/Logs/Musubi for long-run tests
- --route launch argument for scripted tests
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- XcodeGen project: macOS 14, universal (arm64 + x86_64), studio.zielke.musubi
- MusubiKit package: MusubiCore, NDIKit (+ CNDI module map), VideoOutput,
AudioMatrix, DesignSystem (symlink to design/Theme.swift)
- Main window with NDI source list, NDI version logged at launch
- Swift Testing suite for MusubiCore models
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>