Files
info 66ecf55ea9 docs: OpenWiki-Dokumentation und Auto-Update-Workflow hinzufügen
Fügt generierte OpenWiki-Docs (Architektur, Domain, Betrieb, Tests, Workflows)
sowie den GitHub-Actions-Workflow zur automatischen Aktualisierung hinzu.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 14:53:30 +02:00

5.3 KiB

type, title, description, tags
type title description tags
Architecture Architektur-Übersicht 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.
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 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.

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 _<platform>.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.