--- type: Architecture title: Architektur-Übersicht description: whisper-local verwendet ein Factory-Pattern mit typing.Protocol-Interfaces für plattformübergreifende Abstraktion. Die App-Klasse orchestriert alle Module über einen asyncio-Event-Loop. tags: [architecture, factory-pattern, protocol, asyncio, platform-dispatch] --- # Architektur-Übersicht ## Kernprinzip whisper-local ist plattformübergreifend (Linux + Windows) gebaut. Jede plattformabhängige Funktionalität folgt demselben Muster: 1. **`typing.Protocol`-Interface** im Paket-`__init__.py` — keine abstrakte Basisklasse, stattdessen structural subtyping. 2. **Plattformspezifische Backends** in `_linux.py` / `_win32.py` Untermodulen. 3. **Factory-Funktion** (`create_*()`) im Paket-`__init__.py` dispatcht zur Laufzeit auf `sys.platform`. Dieses Muster wird konsequent für Hotkey, Inserter, Media-Controller und Mikrofon-Monitor angewendet. Die Factory-Funktion ist die einzige Stelle, an der Plattform-Logik zentralisiert ist — alle Backends implementieren dasselbe Protocol. ## Module und Abhängigkeiten ``` App (__main__.py) ├── Config (config.py) — TOML-Konfiguration, Dataclass ├── Recorder (recorder.py) — Audio-Aufnahme via sounddevice ├── Transcriber (transcriber.py) — faster-whisper Transkription ├── HotkeyListener (hotkey/) — Systemweiter Hotkey-Listener │ ├── _evdev.py (Linux) │ └── _pynput.py (Windows) ├── Inserter (inserter/) — Text-Einfügung ins aktive Fenster │ ├── _wayland.py (Linux) │ └── _win32.py (Windows) ├── MediaController (media/) — Medien pausieren/während Aufnahme │ ├── _mpris.py (Linux, D-Bus) │ ├── _smtc.py (Windows, SMTC) │ └── _noop.py (Fallback) ├── MicrophoneMonitor (microphone/) — Geräte-Überwachung │ ├── _win32.py (Windows, COM) │ └── _poll.py (Cross-Platform Fallback) └── Tray (tray/) — Tray-Icon, Settings, Notifications ├── _tray.py — PystrayApp + AppState ├── _icon.py — Pillow-Icon-Generierung ├── _settings.py — Tkinter-Einstellungs-Dialog ├── _download_progress.py — Modell-Download-Fortschritt ├── _notification.py — notify-py Wrapper ├── _theme.py — sv-ttk System-Theme ├── _hotkey_record_pynput.py — Windows Hotkey-Aufzeichnung └── _hotkey_record_evdev.py — Linux Hotkey-Aufzeichnung ``` ## App-Klasse — Der Orchestrator Die `App`-Klasse in [`__main__.py`](../../whisper_local/__main__.py) ist der zentrale Orchestrator. Sie instanziiert alle Module im Konstruktor, verdrahtet Callbacks und betreibt den asyncio-Event-Loop. Schlüsselfluss: - `on_press` → Tray auf RECORDING setzen, Medien pausieren, Aufnahme starten. - `on_release` → Aufnahme stoppen, Medien fortsetzen, transkribieren, Text einfügen, Tray auf WAITING. - `_on_config_reload` → Recorder, Monitor, Media und Hotkey zur Laufzeit austauschen — kein Neustart nötig. ### Threading-Modell - **asyncio-Loop** läuft im Main-Thread und verwaltet Hotkey-Listener, Mikrofon-Monitor und Media-Controller. - **pynput** (Windows) betreibt einen eigenen Thread; Callbacks werden via `call_soon_threadsafe` in den asyncio-Loop gebridged. - **pystray** läuft in einem Daemon-Thread; Menu-Callbacks rufen `_on_settings` / `_quit` auf, die wiederum thread-safe in den Loop delegieren. - **Tkinter-Dialoge** (Settings, Download-Fortschritt) laufen in eigenen Daemon-Threads. ### Hotkey-Namen im evdev-Format Key-Namen folgen einheitlich dem evdev-Format (`KEY_F12`, `KEY_LEFTSHIFT`, …) — auch unter Windows. Das pynput-Backend übersetzt intern via `_evdev_to_pynput_key()`. Dies stellt konsistente Konfiguration über Plattformen hinweg sicher. ## Factory-Dispatch-Übersicht | Modul | Factory | Linux-Backend | Windows-Backend | Fallback | |---|---|---|---|---| | Hotkey | `create_listener()` | `EvdevHotkeyListener` | `PynputHotkeyListener` | — | | Inserter | `create_inserter()` | `WaylandInserter` | `Win32Inserter` | — | | Media | `create_media_controller()` | `MprisController` | `SmtcController` | `NoopController` | | Mikrofon | `create_monitor()` | `PollMonitor` | `Win32Monitor` | `PollMonitor` (in `_win32.py` bei COM-Fehler) | | Tray | `create_tray()` | `PystrayApp` | `PystrayApp` | `NoOpTray` | Details zu den einzelnen Backends siehe [Plattform-Abstraktionen](../domain/platform-abstractions.md). ## Circuit-Breaker-Muster `MprisController` und `SmtcController` implementieren einen Circuit-Breaker: Wenn die D-Bus- bzw. SMTC-Verbindung fehlschlägt (`_bus_broken` / `_broken`), wird der Controller dauerhaft deaktiviert und weitere `pause()`/`resume()`-Aufrufe sind No-Ops. Dies verhindert wiederholte Fehler-Logs bei nicht verfügbarer Infrastruktur. ## Erweiterungspunkte - **Neue Plattform hinzufügen**: Neue `_.py`-Datei im jeweiligen Paket, Protocol implementieren, Factory-Funktion um `sys.platform`-Check erweitern. - **Neues Whisper-Modell**: `config.toml` → `[whisper]` `model` ändern. Modelle werden von HuggingFace heruntergeladen. - **Neue Tray-Funktionalität**: Menu in `_tray.py` erweitern, Callback in `App` verdrahten.