feat(app): Mikrofon-Monitor in App integriert
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import logging
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from whisper_local.config import Config, load_config
|
from whisper_local.config import Config, load_config
|
||||||
|
from whisper_local.microphone import create_monitor
|
||||||
from whisper_local.hotkey import create_listener
|
from whisper_local.hotkey import create_listener
|
||||||
from whisper_local.inserter import create_inserter
|
from whisper_local.inserter import create_inserter
|
||||||
from whisper_local.media import create_media_controller
|
from whisper_local.media import create_media_controller
|
||||||
@@ -52,6 +53,10 @@ class App:
|
|||||||
self.hotkey = create_listener(key_name=config.hotkey)
|
self.hotkey = create_listener(key_name=config.hotkey)
|
||||||
self.hotkey.on_press = self.on_press
|
self.hotkey.on_press = self.on_press
|
||||||
self.hotkey.on_release = self.on_release
|
self.hotkey.on_release = self.on_release
|
||||||
|
self.monitor = create_monitor(config.microphone or None)
|
||||||
|
self.monitor.on_device_added = self._on_microphone_added
|
||||||
|
self.monitor.on_device_removed = self._on_microphone_removed
|
||||||
|
self.monitor.on_configured_missing = self._on_configured_microphone_missing
|
||||||
self.tray = create_tray(on_settings=self._open_settings, on_quit=self._quit)
|
self.tray = create_tray(on_settings=self._open_settings, on_quit=self._quit)
|
||||||
|
|
||||||
async def on_press(self) -> None:
|
async def on_press(self) -> None:
|
||||||
@@ -93,6 +98,44 @@ class App:
|
|||||||
from whisper_local.tray._settings import SettingsDialog
|
from whisper_local.tray._settings import SettingsDialog
|
||||||
SettingsDialog(config=self._config, on_save=self._on_config_reload).open()
|
SettingsDialog(config=self._config, on_save=self._on_config_reload).open()
|
||||||
|
|
||||||
|
async def _on_configured_microphone_missing(self) -> None:
|
||||||
|
"""Konfiguriertes Mikrofon nicht gefunden — auf Standard wechseln."""
|
||||||
|
from whisper_local.tray._notification import notify
|
||||||
|
device_name = self._config.microphone or "Mikrofon"
|
||||||
|
logger.warning("Konfiguriertes Mikrofon '%s' nicht gefunden, nutze Standard", device_name)
|
||||||
|
self.recorder = Recorder(
|
||||||
|
sample_rate=self._config.sample_rate,
|
||||||
|
channels=self._config.channels,
|
||||||
|
min_duration=self._config.min_duration,
|
||||||
|
device=None,
|
||||||
|
)
|
||||||
|
notify(
|
||||||
|
"Mikrofon nicht gefunden",
|
||||||
|
f'„{device_name}“ ist nicht verfügbar. Standard-Mikrofon wird verwendet.',
|
||||||
|
)
|
||||||
|
self.tray.set_warning("Mikrofon nicht gefunden")
|
||||||
|
|
||||||
|
async def _on_microphone_added(self, device_name: str) -> None:
|
||||||
|
"""Neues Mikrofon erkannt — konfiguriertes Gerät ggf. wiederherstellen."""
|
||||||
|
if device_name != self._config.microphone:
|
||||||
|
return
|
||||||
|
from whisper_local.tray._notification import notify
|
||||||
|
logger.info("Konfiguriertes Mikrofon '%s' wieder verfügbar", device_name)
|
||||||
|
self.recorder = Recorder(
|
||||||
|
sample_rate=self._config.sample_rate,
|
||||||
|
channels=self._config.channels,
|
||||||
|
min_duration=self._config.min_duration,
|
||||||
|
device=self._config.microphone or None,
|
||||||
|
)
|
||||||
|
notify("Mikrofon verbunden", f'„{device_name}" ist wieder verfügbar.')
|
||||||
|
self.tray.set_warning(None)
|
||||||
|
|
||||||
|
async def _on_microphone_removed(self, device_name: str) -> None:
|
||||||
|
"""Mikrofon entfernt — konfiguriertes Gerät → Fallback auslösen."""
|
||||||
|
logger.info("Mikrofon entfernt: %s", device_name)
|
||||||
|
if device_name == self._config.microphone:
|
||||||
|
await self._on_configured_microphone_missing()
|
||||||
|
|
||||||
def _on_config_reload(self, new_config: Config) -> None:
|
def _on_config_reload(self, new_config: Config) -> None:
|
||||||
"""Übernimmt neue Konfiguration ohne App-Neustart."""
|
"""Übernimmt neue Konfiguration ohne App-Neustart."""
|
||||||
self._config = new_config
|
self._config = new_config
|
||||||
@@ -102,6 +145,14 @@ class App:
|
|||||||
min_duration=new_config.min_duration,
|
min_duration=new_config.min_duration,
|
||||||
device=new_config.microphone or None,
|
device=new_config.microphone or None,
|
||||||
)
|
)
|
||||||
|
self.monitor.stop()
|
||||||
|
self.monitor = create_monitor(new_config.microphone or None)
|
||||||
|
self.monitor.on_device_added = self._on_microphone_added
|
||||||
|
self.monitor.on_device_removed = self._on_microphone_removed
|
||||||
|
self.monitor.on_configured_missing = self._on_configured_microphone_missing
|
||||||
|
if self._loop is not None:
|
||||||
|
asyncio.run_coroutine_threadsafe(self.monitor.start(), self._loop)
|
||||||
|
self.tray.set_warning(None)
|
||||||
old_media = self.media
|
old_media = self.media
|
||||||
self.media = create_media_controller(
|
self.media = create_media_controller(
|
||||||
enabled=new_config.pause_media_during_recording
|
enabled=new_config.pause_media_during_recording
|
||||||
@@ -128,6 +179,7 @@ class App:
|
|||||||
logger.info("whisper-local gestartet, warte auf Hotkey...")
|
logger.info("whisper-local gestartet, warte auf Hotkey...")
|
||||||
self.tray.start()
|
self.tray.start()
|
||||||
self._hotkey_task = asyncio.create_task(self.hotkey.listen())
|
self._hotkey_task = asyncio.create_task(self.hotkey.listen())
|
||||||
|
asyncio.create_task(self.monitor.start())
|
||||||
await self._quit_event.wait()
|
await self._quit_event.wait()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user