You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Musubi/docs/02-architektur.md

52 lines
3.1 KiB

# Architektur
## Überblick
```
Technik-Netz Musubi (MacBook, Regie) Ausgänge
────────────── ─────────────────────────── ─────────────────────
ZowieBox MV ─NDI|HX3─▶ NDIKit ──▶ VideoOutput ───────────────▶ Regie-Bildschirm
ZowieBox PGM ─NDI|HX3─▶ │
└──▶ AudioMatrix ──────────────────▶ MOTU M2 Out 1/2 → Ui12
Headset-Mikro ─────────────────▶ AudioMatrix
ATEM ─────────Status───▶ Tally ──▶ Intercom ◀──WebRTC──▶ Handy im OP (Klinik-Netz)
MusubiCore (Szenen) ─Bonjour─▶ Mac mini (Knoten, Bühne)
```
Der Mac mini empfängt NDI selbst direkt aus dem Technik-Netz und wird von der Regie nur gesteuert.
## Module
| Modul | Aufgabe | Technik |
|---|---|---|
| MusubiCore | Modelle (Quelle, Ausgang, Route, Szene), Persistenz, Einstellungen | Swift, Codable/JSON, Swift Testing |
| NDIKit | Quellen finden, empfangen (Video+Audio oder nur Audio), Statistik | NDI SDK (C), `NDIlib_find_*`, `NDIlib_recv_*`, Bandbreite `audio_only` für reinen Ton |
| VideoOutput | Frames darstellen, ein Vollbildfenster je `NSScreen`, Anzeigemodus 50 Hz | Metal oder `AVSampleBufferDisplayLayer`, `CGDisplayCopyAllDisplayModes` |
| AudioMatrix | Quellen → Ausgangskanäle, Gain, Mute, Pegel, Sprechtaste | Core Audio / `AVAudioEngine`, Kanalzuordnung (`channelMap`) |
| Remote | Regie ↔ Knoten: Szene setzen, Status melden | Bonjour (`NWListener`/`NWBrowser`), JSON-Nachrichten |
| Intercom | Web-Seite, Signalisierung, Audio hin/zurück, PGM-Vorschau | eingebetteter HTTPS-Server, WebRTC (Opus, H.264 via VideoToolbox), Bindung an Schnittstelle |
| Tally | PGM/Vorschau-Eingänge des ATEM lesen | Blackmagic ATEM Switchers SDK |
## Datenmodell (Entwurf)
```swift
struct Source: Codable, Hashable { var ndiName: String; var label: String }
enum Output: Codable, Hashable { case screen(displayID: UInt32), audioChannel(deviceUID: String, channel: Int) }
struct Route: Codable, Hashable { var source: Source; var output: Output; var mode: Mode
enum Mode: String, Codable { case videoAndAudio, videoOnly, audioOnly } }
struct Scene: Codable, Identifiable { var id: UUID; var name: String; var role: Role; var routes: [Route] }
enum Role: String, Codable { case control, node }
```
## Threads
- NDI-Empfang je Quelle auf eigener Queue.
- Video: Frames ohne Kopie an die Darstellung (CVPixelBuffer), Rendern im Takt des Displays.
- Audio: Ringpuffer zwischen NDI-Empfang und Render-Callback, keine Allokationen im Callback, Drift-Ausgleich (Resampling) zwischen NDI-Takt und Interface-Takt.
## Netzwerk-Bindung
- NDI, Bonjour, Remote: nur Technik-Schnittstelle.
- Intercom: nur Klinik-Schnittstelle (oder TURN-Relay nach außen).
- Schnittstellen in den Einstellungen per Name wählbar (z. B. `en7` Technik, `en0` Klinik).

Powered by TurnKey Linux.