S SmartDocs
Chuỗi bài: Ricky python 74 dòng · Cập nhật 2026-04-07

voice.py

Ricky/RAG_project/io/voice.py

"""
Voice input (Cantonese / Google STT) and console text helpers.
"""
import logging
from config.runtime import (
    get_voice_language,
    get_voice_timeout,
    get_voice_phrase_time_limit,
)

logger = logging.getLogger(__name__)

try:
    import speech_recognition as sr
except Exception:
    sr = None  # type: ignore


def to_console_text(text: str) -> str:
    """Encode to cp950 (Windows Traditional Chinese) to avoid console errors.
    Falls back to the original string on non-Windows or unsupported characters.
    """
    try:
        return text.encode("cp950", errors="replace").decode("cp950")
    except Exception:
        return text


def init_voice_input():
    """Return (recognizer, microphone) or (None, None) if unavailable."""
    if sr is None:
        return None, None
    try:
        recognizer = sr.Recognizer()
        microphone = sr.Microphone()
        return recognizer, microphone
    except Exception as e:
        logger.warning("Voice input init failed: %s", e)
        return None, None


def get_voice_question(recognizer, microphone) -> str | None:
    """Record audio and transcribe it; returns transcribed text or None."""
    if not recognizer or not microphone:
        return None

    language = get_voice_language()
    timeout = get_voice_timeout()
    phrase_time_limit = get_voice_phrase_time_limit()

    try:
        with microphone as source:
            recognizer.adjust_for_ambient_noise(source, duration=0.4)
            print("[VOICE] Please speak your question now...")
            audio = recognizer.listen(
                source,
                timeout=timeout,
                phrase_time_limit=phrase_time_limit,
            )
        text = recognizer.recognize_google(audio, language=language).strip()
        if text:
            print(f"[VOICE] Recognized: {to_console_text(text)}")
            return text
        return None
    except sr.WaitTimeoutError:
        print("[WARN] Voice input timed out. Please try again.")
        return None
    except sr.UnknownValueError:
        print("[WARN] Could not understand audio. Please try again.")
        return None
    except Exception as e:
        logger.warning("Speech recognition failed: %s", e)
        print(f"[WARN] Speech-to-text failed: {e}")
        return None

Bài viết liên quan