base_agent/uas/inout/outputs/speech_output.py

69 lines
2.5 KiB
Python
Raw Normal View History

2026-06-18 03:28:14 +00:00
import logger
import pyttsx3
from PyQt5.QtWidgets import QWidget, QPushButton, QVBoxLayout, QLabel
from uas.io.base_io import BaseOutput, IOType, IOData
from uas.io.outputs.text_output import HAS_TTS
from uas.io.signals import io_signals
class SpeechOutput(BaseOutput):
def __init__(self):
super().__init__("speech_output", [IOType.TEXT, IOType.SPEECH])
self._engine = None
if HAS_TTS:
self._init_tts()
def _init_tts(self):
try:
self._engine = pyttsx3.init()
self._engine.setProperty("rate", 180)
self._engine.setProperty("volume", 0.9)
logger.info("✅ TTS 引擎初始化成功")
except Exception as e:
logger.error(f"TTS 初始化失败: {e}")
def render(self, data: IOData) -> None:
text = str(data.processed or data.raw)
self._tts_label.setText(f"朗读: {text[:80]}...")
if not self._mute_btn.isChecked() and self._engine:
try:
self._engine.say(text)
self._engine.runAndWait()
io_signals.tts_finished.emit(text)
except Exception as e:
logger.error(f"TTS 朗读失败: {e}")
# ─────────────────────────────────────────────────────────────────
# 语音输出TTS
# ─────────────────────────────────────────────────────────────────
class SpeechOutputWidget(QWidget, SpeechOutput):
"""
语音输出TTS组件
基于 pyttsx3在独立 QThread 中朗读不阻塞 UI
"""
def __init__(self, parent=None):
QWidget.__init__(self, parent)
SpeechOutput.__init__(self)
self._build_ui()
def _build_ui(self):
layout = QVBoxLayout(self)
layout.setContentsMargins(8, 8, 8, 8)
title = QLabel("🔊 语音输出 (TTS)")
title.setStyleSheet("font-weight: bold; font-size: 13px;")
layout.addWidget(title)
self._tts_label = QLabel("等待输出...")
self._tts_label.setWordWrap(True)
self._tts_label.setStyleSheet(
"background:#e8f5e9; padding:6px; border-radius:4px;"
)
layout.addWidget(self._tts_label)
self._mute_btn = QPushButton("🔇 静音")
self._mute_btn.setCheckable(True)
layout.addWidget(self._mute_btn)