112 lines
3.3 KiB
Python
112 lines
3.3 KiB
Python
# main.py
|
|
import os
|
|
import queue
|
|
import sys
|
|
import threading
|
|
|
|
def _setup_error_log():
|
|
"""Last-resort error log for crashes before tray appears (frozen mode)."""
|
|
if not getattr(sys, "frozen", False):
|
|
return
|
|
import traceback
|
|
if os.name == "nt":
|
|
log_dir = os.path.join(os.environ.get("LOCALAPPDATA", ""), "WhisperDictation")
|
|
else:
|
|
log_dir = os.path.join(os.path.expanduser("~"), ".local", "share", "WhisperDictation")
|
|
os.makedirs(log_dir, exist_ok=True)
|
|
log_path = os.path.join(log_dir, "error.log")
|
|
sys.excepthook = lambda *args: open(log_path, "a").write(
|
|
"".join(traceback.format_exception(*args)) + "\n"
|
|
)
|
|
|
|
def main():
|
|
_setup_error_log()
|
|
|
|
from whisper_app import app, config, audio, transcriber, hotkey
|
|
from whisper_app import overlay, tray, log_window, settings_window, vocab_window
|
|
import tkinter as tk
|
|
|
|
config.load_config()
|
|
config.load_vocab()
|
|
|
|
# Tkinter root (hidden)
|
|
root = tk.Tk()
|
|
root.withdraw()
|
|
app.overlay_tk = root
|
|
|
|
# Log queue — connect before model load so early messages appear
|
|
log_q: queue.Queue = queue.Queue()
|
|
app.set_log_queue(log_q)
|
|
|
|
# Windows
|
|
overlay.create(root)
|
|
log_win = log_window.create(
|
|
root, log_q,
|
|
on_settings=lambda: settings_window.open(root, _reload),
|
|
on_vocab=lambda: vocab_window.open(root),
|
|
)
|
|
|
|
# Load model in background so the tray appears immediately
|
|
threading.Thread(target=transcriber.load_model, daemon=True).start()
|
|
|
|
# Audio stream with device hotplug monitoring
|
|
app.audio_manager = audio.AudioManager()
|
|
app.audio_manager.start()
|
|
|
|
# Hotkey
|
|
def _on_release():
|
|
threading.Thread(target=transcriber.stop_and_transcribe, daemon=True).start()
|
|
|
|
app.hotkey_listener = hotkey.HotkeyListener(
|
|
config.config["hotkey"],
|
|
on_press=_start_recording,
|
|
on_release=_on_release,
|
|
)
|
|
|
|
# Tray
|
|
icon = tray.create(
|
|
on_settings=lambda: settings_window.open(root, _reload),
|
|
on_vocab=lambda: vocab_window.open(root),
|
|
on_show_log=lambda: root.after(0, log_window.show),
|
|
on_quit=lambda: _quit(icon),
|
|
)
|
|
threading.Thread(target=icon.run, daemon=True).start()
|
|
|
|
app.log(f"Bereit. Hotkey: {config.config['hotkey']}")
|
|
root.mainloop()
|
|
app.audio_manager.stop()
|
|
|
|
def _start_recording():
|
|
from whisper_app import app, transcriber
|
|
app.audio_chunks = []
|
|
transcriber.set_state(app.AppState.RECORDING)
|
|
app.log("Recording...")
|
|
|
|
def _reload():
|
|
from whisper_app import app, config, transcriber, hotkey
|
|
if app.hotkey_listener:
|
|
app.hotkey_listener.stop()
|
|
threading.Thread(target=transcriber.load_model, daemon=True).start()
|
|
if app.audio_manager:
|
|
app.audio_manager.restart()
|
|
app.hotkey_listener = hotkey.HotkeyListener(
|
|
config.config["hotkey"],
|
|
on_press=_start_recording,
|
|
on_release=lambda: threading.Thread(
|
|
target=transcriber.stop_and_transcribe, daemon=True).start(),
|
|
)
|
|
app.log(f"Hotkey aktualisiert: {config.config['hotkey']}")
|
|
|
|
def _quit(icon):
|
|
from whisper_app import app
|
|
if app.audio_manager:
|
|
app.audio_manager.stop()
|
|
icon.stop()
|
|
if app.overlay_tk:
|
|
app.overlay_tk.after(0, app.overlay_tk.quit)
|
|
|
|
if __name__ == "__main__":
|
|
import multiprocessing
|
|
multiprocessing.freeze_support()
|
|
main()
|