72 lines
2.6 KiB
Python
72 lines
2.6 KiB
Python
import os
|
|
import logging
|
|
from faster_whisper import WhisperModel
|
|
import sqlite3
|
|
from datetime import datetime
|
|
from pydub import AudioSegment
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
class VoiceService:
|
|
def __init__(self, db_path: str, model_size: str = "small"):
|
|
self.db_path = db_path
|
|
self.model_size = model_size
|
|
# CPU-only optimization: int8 is fast on standard CPUs
|
|
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:
|
|
try:
|
|
start_time = datetime.now()
|
|
|
|
# Convert to wav if needed (Telegram uses .oga/.ogg)
|
|
wav_path = file_path.rsplit('.', 1)[0] + ".wav"
|
|
audio = AudioSegment.from_file(file_path)
|
|
duration = int(len(audio) / 1000)
|
|
audio.export(wav_path, format="wav")
|
|
|
|
segments, info = self.model.transcribe(wav_path, beam_size=5)
|
|
text = " ".join([segment.text for segment in segments]).strip()
|
|
|
|
# Clean up temp files
|
|
if os.path.exists(wav_path): os.remove(wav_path)
|
|
|
|
# Log to DB
|
|
self._log_to_db(user_id, username, msg_type, duration, text)
|
|
|
|
return text
|
|
except Exception as e:
|
|
logger.error(f"Transcription error: {e}")
|
|
return f"[Ошибка распознавания]: {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}")
|
|
|
|
# Global instance will be initialized in main.py or handlers
|