ускоренная работа

This commit is contained in:
2026-01-09 19:59:31 +03:00
parent ce28fede74
commit fd373d83f3
10 changed files with 322 additions and 46 deletions

View File

@@ -13,7 +13,7 @@ import sys
import json
import pyaudio
from vosk import Model, KaldiRecognizer
from ..core.config import VOSK_MODEL_PATH, SAMPLE_RATE
from config import VOSK_MODEL_PATH, SAMPLE_RATE
class LocalRecognizer:

View File

@@ -20,6 +20,7 @@ from deepgram import (
)
import deepgram.clients.common.v1.abstract_sync_websocket as sdk_ws
import websockets.sync.client
from ..core.audio_manager import get_audio_manager
# --- Патч (исправление) для библиотеки websockets ---
# По умолчанию Deepgram SDK использует слишком короткий таймаут подключения.
@@ -63,7 +64,7 @@ class SpeechRecognizer:
)
self.dg_client = DeepgramClient(DEEPGRAM_API_KEY, config)
self.pa = pyaudio.PyAudio()
self.pa = get_audio_manager().get_pyaudio()
print("✅ Deepgram клиент готов")
def _get_stream(self):
@@ -135,38 +136,71 @@ class SpeechRecognizer:
channels=1,
sample_rate=SAMPLE_RATE,
interim_results=True,
utterance_end_ms=1200, # Пауза 1.2с считается концом фразы
utterance_end_ms=1000, # Пауза 1.0с считается концом фразы (было 1.2)
vad_events=True,
)
if dg_connection.start(options) is False:
print("Failed to start Deepgram connection")
return
# --- Задача отправки аудио ---
# --- Задача отправки аудио с буферизацией ---
async def send_audio():
chunks_sent = 0
audio_buffer = [] # Буфер для накопления звука во время подключения
try:
# 1. Сразу начинаем захват звука, не дожидаясь сети!
stream.start_stream()
print("🎤 Stream started, sending audio...")
print("🎤 Stream started (buffering)...")
# 2. Запускаем подключение к Deepgram в фоне (через ThreadPool, т.к. start() блокирующий)
# Но в данном SDK start() возвращает bool, он может быть блокирующим.
# Deepgram Python SDK v3+ start() делает handshake.
connect_future = loop.run_in_executor(
None, lambda: dg_connection.start(options)
)
# Пока подключаемся, копим данные
while not connect_future.done():
if stream.is_active():
data = stream.read(4096, exception_on_overflow=False)
audio_buffer.append(data)
await asyncio.sleep(0.001)
# Проверяем результат подключения
if connect_future.result() is False:
print("Failed to start Deepgram connection")
return
print(f"🚀 Connected! Sending buffer ({len(audio_buffer)} chunks)...")
# 3. Отправляем накопленный буфер
for chunk in audio_buffer:
dg_connection.send(chunk)
chunks_sent += 1
audio_buffer = None # Освобождаем память
# 4. Продолжаем стримить в реальном времени
while not stop_event.is_set():
if stream.is_active():
data = stream.read(4096, exception_on_overflow=False)
# Отправка данных (синхронная в этой версии SDK)
dg_connection.send(data)
chunks_sent += 1
if chunks_sent % 50 == 0:
print(f".", end="", flush=True)
# Уступаем время другим задачам
await asyncio.sleep(0.005)
except Exception as e:
print(f"Audio send error: {e}")
finally:
stream.stop_stream()
if stream.is_active():
stream.stop_stream()
print(f"\n🛑 Stream stopped. Chunks sent: {chunks_sent}")
sender_task = asyncio.create_task(send_audio())
if False: # dg_connection.start(options) перенесен внутрь send_audio
pass
try:
# 1. Ждем начала речи (если задан detection_timeout)
if detection_timeout:
@@ -254,8 +288,7 @@ class SpeechRecognizer:
self.stream.stop_stream()
self.stream.close()
self.stream = None
if self.pa:
self.pa.terminate()
# self.pa.terminate() - Используем общий менеджер
# Глобальный экземпляр

View File

@@ -10,6 +10,7 @@ import pvporcupine
import pyaudio
import struct
from ..core.config import PORCUPINE_ACCESS_KEY, PORCUPINE_KEYWORD_PATH
from ..core.audio_manager import get_audio_manager
class WakeWordDetector:
@@ -28,7 +29,8 @@ class WakeWordDetector:
access_key=PORCUPINE_ACCESS_KEY, keyword_paths=[str(PORCUPINE_KEYWORD_PATH)]
)
self.pa = pyaudio.PyAudio()
# Используем общий экземпляр PyAudio
self.pa = get_audio_manager().get_pyaudio()
self._open_stream()
print("🎤 Ожидание wake word 'Alexandr'...")
@@ -138,8 +140,7 @@ class WakeWordDetector:
def cleanup(self):
"""Освобождение ресурсов при выходе."""
self.stop_monitoring()
if self.pa:
self.pa.terminate()
# self.pa.terminate() - Не делаем этого, так как PyAudio общий
if self.porcupine:
self.porcupine.delete()