import sounddevice as sd from vosk import Model, KaldiRecognizer import json import sys import numpy as np # 1. Настройки MODEL_PATH = r"D:\Work\Software_Development\Projects\vosk\vosk-model-small-ru-0.22" # Попробуйте 48000, если снова будет ошибка -9997 SAMPLERATE = 48000 model = Model(MODEL_PATH) # 2. Поиск ID (Potato использует имена B1 и B2) def find_devices(): id_gm = None # VoiceMeeter B1 id_pcs = None # VoiceMeeter B2 for i, d in enumerate(sd.query_devices()): if "Voicemeeter Out B1" in d['name']: id_gm = i if "Voicemeeter Out B2" in d['name']: id_pcs = i return id_gm, id_pcs id_gm, id_pcs = find_devices() if id_gm is None or id_pcs is None: print("Ошибка: Устройства B1 или B2 не найдены!") sys.exit() # 3. Распознаватели rec_gm = KaldiRecognizer(model, SAMPLERATE) rec_pcs = KaldiRecognizer(model, SAMPLERATE) def create_callback(rec, role): def callback(indata, frames, time, status): # Если звук тихий, не мучаем Vosk if np.max(np.abs(indata)) < 0.001: return if rec.AcceptWaveform(bytes(indata)): text = json.loads(rec.Result())['text'] if text: print(f"[{role}]: {text}") '''else: # Частичный результат для динамики partial = json.loads(rec.PartialResult())['partial'] if partial: # Используем \b для удаления "слышит" при финальном результате sys.stdout.write(f"\r[{role} говорит...]: {partial}".ljust(60)) sys.stdout.flush()''' return callback # 4. Параллельный запуск print(f"--- ЗАПУСК ТРАНСКРИБАЦИИ TTRPG ---") print(f"GM (Микрофон B1) ID: {id_gm}") print(f"PCs (Система B2) ID: {id_pcs}") try: with sd.RawInputStream(samplerate=SAMPLERATE, blocksize=8000, device=id_gm, dtype='int16', channels=1, callback=create_callback(rec_gm, "GM")), \ sd.RawInputStream(samplerate=SAMPLERATE, blocksize=8000, device=id_pcs, dtype='int16', channels=1, callback=create_callback(rec_pcs, "PCs")): print("\nСистема готова. GM может начинать сессию, PCs могут перебивать.") while True: sd.sleep(1000) except Exception as e: print(f"\nОшибка: {e}")