domovoy_bot/services/voice_service.py

78 lines
2.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
import logging
from faster_whisper import WhisperModel
import sqlite3
from datetime import datetime
from pydub import AudioSegment
from pathlib import Path
logger = logging.getLogger(__name__)
# ЖЕСТКИЙ ФИКС ПУТЕЙ К БИНАРНИКАМ
AudioSegment.converter = "/usr/bin/ffmpeg"
AudioSegment.ffprobe = "/usr/bin/ffprobe"
class VoiceService:
def __init__(self, db_path: str, model_size: str = "small"):
self.db_path = db_path
self.model_size = model_size
logger.info(f"💾 Загрузка модели Whisper ({model_size})...")
self.model = WhisperModel(model_size, device="cpu", compute_type="int8")
self._init_db()
def _init_db(self):
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS voice_recognition_logs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER,
username TEXT,
message_type TEXT,
duration INTEGER,
text TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
conn.commit()
conn.close()
def transcribe(self, file_path: str, user_id: int, username: str, msg_type: str) -> str:
f_path = Path(file_path)
if not f_path.exists():
raise FileNotFoundError(f"Файл не найден: {file_path}")
try:
logger.info(f"🔄 Конвертация {f_path.name}...")
wav_path = str(f_path.with_suffix('.wav'))
# Конвертируем
audio = AudioSegment.from_file(str(f_path))
duration = int(len(audio) / 1000)
audio.export(wav_path, format="wav")
logger.info(f"🧠 Расшифровка ({duration}с)...")
segments, info = self.model.transcribe(wav_path, beam_size=5)
text = " ".join([segment.text for segment in segments]).strip()
# Чистим за собой
if os.path.exists(wav_path): os.remove(wav_path)
self._log_to_db(user_id, username, msg_type, duration, text)
return text
except Exception as e:
logger.error(f"❌ Ошибка транскрибации: {e}", exc_info=True)
raise e
def _log_to_db(self, user_id, username, msg_type, duration, text):
try:
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute('''
INSERT INTO voice_recognition_logs (user_id, username, message_type, duration, text)
VALUES (?, ?, ?, ?, ?)
''', (user_id, username, msg_type, duration, text))
conn.commit()
conn.close()
except Exception as e:
logger.error(f"DB Log error: {e}")