Files
whisper-local/openwiki/domain/platform-abstractions.md
T
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

6.1 KiB

type, title, description, tags
type title description tags
Domain Plattform-Abstraktionen Die vier plattformabhängigen Module — Hotkey, Inserter, Media, Mikrofon — mit ihren jeweiligen Linux- und Windows-Backends. Protocol-Interfaces, Factory-Dispatch und implementierungsspezifische Details.
domain
platform-abstraction
hotkey
inserter
media
microphone
protocol
factory

Plattform-Abstraktionen

whisper-local abstrahiert vier plattformabhängige Funktionsbereiche hinter typing.Protocol-Interfaces mit Factory-Dispatch. Die Architektur-Übersicht beschreibt das generelle Muster; hier werden die konkreten Backends dokumentiert.

HotkeyListener

Protocol: HotkeyListener in hotkey/__init__.py Attribute: on_press: AsyncCallback | None, on_release: AsyncCallback | None Methoden: async listen(), stop()

EvdevHotkeyListener (Linux)

Datei: hotkey/_evdev.py

  • find_keyboard_devices(key_name) durchsucht alle /dev/input/-Devices und findet jene, die den konfigurierten Key unterstützen. Wirft RuntimeError wenn kein passendes Device gefunden wird.
  • listen() startet pro gefundenem Device einen asyncio.Task mit async_read_loop(). Dadurch werden alle Tastaturen parallel überwacht — wichtig bei Multi-Device-Setups.
  • stop() cancelt alle Tasks und schließt Devices.

PynputHotkeyListener (Windows/Fallback)

Datei: hotkey/_pynput.py

  • _evdev_to_pynput_key() übersetzt evdev-Namen (KEY_F12) ins pynput-Format (Key.f12). Unterstützt F-Tasten per Regex und direkte Attribut-Zuordnung.
  • Key-Repeat-Unterdrückung: Das _pressed-Flag verhindert, dass OS-Key-Repeat mehrfache on_press-Callbacks auslöst. Erst beim echten on_release wird das Flag zurückgesetzt.
  • pynput betreibt einen Thread; Callbacks werden via call_soon_threadsafe + asyncio.ensure_future in den Loop gebridged.
  • stop() signalisiert über ein asyncio.Event; der Listener wird im finally-Block gestoppt.

Inserter

Protocol: Inserter in inserter/__init__.py Methode: async insert(text: str)

Beide Backends sichern den alten Clipboard-Inhalt, setzen den Text, senden Ctrl+V, und restaurieren das Clipboard im finally-Block. PASTE_DELAY = 0.2s nach dem Paste-Befehl.

WaylandInserter (Linux)

Datei: inserter/_wayland.py

  • Clipboard-Backup via wl-paste --no-newline.
  • Text setzen via wl-copy -- <text>.
  • Ctrl+V simulieren via ydotool key 29:1 47:1 47:0 29:0 (evdev Keycodes für Ctrl down, V down, V up, Ctrl up).
  • Erfordert ydotool-Daemon und input-Gruppen-Mitgliedschaft.

Win32Inserter (Windows)

Datei: inserter/_win32.py

  • Clipboard-Operationen via win32clipboard (CF_UNICODETEXT).
  • Ctrl+V via pynput.keyboard.Controller.
  • Blocking-Aufrufe werden mit asyncio.to_thread() in Threads ausgelagert, um den Event-Loop nicht zu blockieren.

MediaController

Protocol: MediaController in media/__init__.py Methoden: async pause(), async resume()

create_media_controller(enabled) gibt NoopController zurück wenn enabled=False oder die Plattform nicht unterstützt wird.

MprisController (Linux)

Datei: media/_mpris.py

  • Verbindet sich via dbus-next (MessageBus().connect()) zur D-Bus-Session.
  • pause(): Listet alle org.mpris.MediaPlayer2.*-Services auf, pausiert nur Sessions im Status Playing, merkt sich pausierte Bus-Namen in _paused.
  • resume(): Setzt nur die Sessions fort, die selbst pausiert wurden (_paused-Liste).
  • Circuit-Breaker: _bus_broken-Flag deaktiviert den Controller dauerhaft bei D-Bus-Verbindungsfehler.

SmtcController (Windows)

Datei: media/_smtc.py

  • Nutzt winrt.windows.media.control.GlobalSystemMediaTransportControlsSessionManager.
  • pause(): Iteriert über alle Sessions, pausiert nur PLAYING-Sessions via try_pause_async(), merkt sich AUMIDs in _paused.
  • resume(): Holt aktuelle Sessions, spielt nur die in _paused gelisteten via try_play_async() wieder ab. Überspringt Sessions, die nicht mehr existieren.
  • Circuit-Breaker: _broken-Flag bei SMTC-Initialisierungsfehler.

NoopController

Datei: media/_noop.py

  • pause() und resume() sind No-Ops. Wird verwendet wenn das Feature deaktiviert ist oder die Plattform nicht unterstützt wird.

Mikrofon-Monitor

Protocol: MicrophoneMonitor in microphone/__init__.py Callbacks: on_device_added, on_device_removed, on_configured_missing (alle Awaitable) Methoden: async start(), stop()

PollMonitor (Cross-Platform)

Datei: microphone/_poll.py

  • Pollt sounddevice.query_devices() alle 2,5 s, vergleicht mit _known_devices.
  • start() prüft sofort ob das konfigurierte Gerät vorhanden ist und ruft on_configured_missing() auf wenn nicht.
  • Bei Fehler beim Abfragen der Geräte wird der bisherige Stand beibehalten (kein Crash).

Win32Monitor (Windows)

Datei: microphone/_win32.py

  • Definiert COM-Interfaces (IMMNotificationClient, IMMDeviceEnumerator) via comtypes zur Laufzeit.
  • Registriert einen IMMNotificationClient-Callback bei der Core Audio API. COM-Events werden via call_soon_threadsafe in den asyncio-Loop delegiert.
  • Polling-Fallback: Wenn COM-Initialisierung fehlschlägt, wird automatisch ein PollMonitor als Fallback gestartet.
  • stop() deregistriert den COM-Callback und ruft CoUninitialize() auf.

Geräte-Erkennungslogik

Alle Monitors verwenden dieselbe Logik: sd.query_devices() filtern auf max_input_channels > 0 (Eingabegeräte) und extrahieren Gerätenamen. Der Vergleich erfolgt über Set-Differenzen (added = current - known, removed = known - current).