diff --git a/app/api.py b/app/api.py index 353ad27..1332c08 100644 --- a/app/api.py +++ b/app/api.py @@ -378,7 +378,7 @@ def regenerate_message(): from app.voice_service import VoiceService, VOICE_COMMANDS_RESPONSE_TO_STORE # 1. Создаем экземпляр (обязательно укажите путь к вашей модели Vosk) -voice_inst = VoiceService(model_path=r"D:\\Work\\Software_Development\\Projects\\vosk\\vosk-model-small-ru-0.22") +voice_inst = VoiceService() current_obsidian_settings = {} @@ -419,6 +419,13 @@ def sync_settings(): abs_path=data.get('absoluteLogsPath') ) + # Инициализируем модель Vosk, если передан путь + vosk_path = data.get('voskModelPath') + if vosk_path: + # Запускаем в фоновом потоке, чтобы не подвесить фронтенд Obsidian (загрузка занимает время) + import threading + threading.Thread(target=voice_inst.load_model, args=(vosk_path,), daemon=True).start() + # TODO: Скорее всего, здесь нужно какое-то событие эмитировать об изменении настроек, и в другом месте ловить graph_history_manager.title_generator.llm = get_llm(current_obsidian_settings['summarizationModel']) graph_history_manager.title_generator.voice_llm = get_llm(current_obsidian_settings['voiceCommandModel']) diff --git a/app/voice_service.py b/app/voice_service.py index 8e3ca89..2817003 100644 --- a/app/voice_service.py +++ b/app/voice_service.py @@ -20,10 +20,10 @@ import pandas as pd VOICE_COMMANDS_RESPONSE_TO_STORE = 3 class VoiceService: - def __init__(self, model_path, samplerate=48000): - self.model_path = model_path + def __init__(self, samplerate=48000): + self.model_path = None self.samplerate = samplerate - self.model = Model(model_path) + self.model = None self.is_running = False self.current_file = None self.history = [] @@ -41,6 +41,43 @@ class VoiceService: self._stop_event = threading.Event() self.abs_logs_path = None + # Переменная для отслеживания состояния загрузки, чтобы не грузить модель дважды + self.is_loading_model = False + + def load_model(self, path): + """Загружает модель Vosk, если она еще не загружена или путь изменился.""" + if not path or not path.strip(): + return + + # Если путь не изменился и модель уже есть, ничего не делаем + if self.model_path == path and self.model is not None: + return + + if self.is_loading_model: + return + + try: + self.is_loading_model = True + if not os.path.exists(path): + print(f"❌ Vosk: Папка с моделью не найдена по пути: {path}") + return + + print(f"⏳ Vosk: Начинается фоновая загрузка модели из {path}...") + # Принудительно останавливаем сессию, если подменяем модель на ходу + if self.is_running: + self.stop_session() + + from vosk import Model + self.model = Model(path) + self.model_path = path + print("✅ Vosk: Модель успешно загружена и готова к работе.") + except Exception as e: + print(f"❌ Vosk: Ошибка при загрузке модели: {e}") + self.model = None + self.model_path = None + finally: + self.is_loading_model = False + def update_logs_config(self, abs_path): """Обновление путей из настроек Obsidian.""" self.abs_logs_path = abs_path @@ -74,6 +111,10 @@ class VoiceService: print(f"Error loading history from file: {e}") def start_session(self, continue_last=False): + if self.model is None: + print("⚠️ Vosk: Попытка старта транскрибации, но модель еще не загружена или путь не указан в настройках Obsidian!") + return + if self.is_running: return # Очистка вкладок при новом старте