Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -86,6 +86,9 @@
|
|
| 86 |
},
|
| 87 |
}
|
| 88 |
|
|
|
|
|
|
|
|
|
|
| 89 |
# ---------------------------------------------------------------------------
|
| 90 |
# 4. 安全 TTS 合成
|
| 91 |
# ---------------------------------------------------------------------------
|
|
@@ -188,6 +191,48 @@ def on_translate_click(src_text, src_lang_choice, tgt_lang_choice, history):
|
|
| 188 |
history.append({"role": "assistant", "content": f"⚠️ 翻译失败: {str(e)}"})
|
| 189 |
return history, None
|
| 190 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 191 |
# ---------------------------------------------------------------------------
|
| 192 |
# 6. Gradio 界面设计 (支持源语重放 + 灵活切换目的语)
|
| 193 |
# ---------------------------------------------------------------------------
|
|
@@ -267,6 +312,13 @@ def on_translate_click(src_text, src_lang_choice, tgt_lang_choice, history):
|
|
| 267 |
outputs=[chatbot, audio_out]
|
| 268 |
)
|
| 269 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 270 |
if __name__ == "__main__":
|
| 271 |
port = int(os.environ.get("PORT", 7860))
|
| 272 |
demo.queue().launch(
|
|
|
|
| 86 |
},
|
| 87 |
}
|
| 88 |
|
| 89 |
+
# 语言标签 -> TTS 音色,用于"点击历史记录气泡重新合成语音"
|
| 90 |
+
TAG_TO_VOICE = {cfg["tag"]: cfg["voice"] for cfg in INTERSECTION_LANGS.values()}
|
| 91 |
+
|
| 92 |
# ---------------------------------------------------------------------------
|
| 93 |
# 4. 安全 TTS 合成
|
| 94 |
# ---------------------------------------------------------------------------
|
|
|
|
| 191 |
history.append({"role": "assistant", "content": f"⚠️ 翻译失败: {str(e)}"})
|
| 192 |
return history, None
|
| 193 |
|
| 194 |
+
def _extract_message_text(value):
|
| 195 |
+
"""
|
| 196 |
+
从 Chatbot 点击事件 (SelectData.value) 中提取纯文本。
|
| 197 |
+
Gradio 6.x messages 格式下,content 既可能是字符串,
|
| 198 |
+
也可能是 [{"type": "text", "text": "..."}] 形式的内容块列表,
|
| 199 |
+
这里统一兼容处理。
|
| 200 |
+
"""
|
| 201 |
+
if isinstance(value, dict):
|
| 202 |
+
content = value.get("content", value)
|
| 203 |
+
else:
|
| 204 |
+
content = value
|
| 205 |
+
|
| 206 |
+
if isinstance(content, list):
|
| 207 |
+
parts = []
|
| 208 |
+
for block in content:
|
| 209 |
+
if isinstance(block, dict):
|
| 210 |
+
parts.append(block.get("text", ""))
|
| 211 |
+
else:
|
| 212 |
+
parts.append(str(block))
|
| 213 |
+
return "".join(parts)
|
| 214 |
+
|
| 215 |
+
return str(content) if content is not None else ""
|
| 216 |
+
|
| 217 |
+
def on_history_select(evt: gr.SelectData):
|
| 218 |
+
"""步骤 5(可选):点击历史记录中的任意一条气泡,用对应语言音色重新合成语音"""
|
| 219 |
+
text = _extract_message_text(evt.value)
|
| 220 |
+
|
| 221 |
+
m = re.match(r"^\[(.+?)\]\s*(.*)$", text, flags=re.S)
|
| 222 |
+
if not m:
|
| 223 |
+
return gr.update()
|
| 224 |
+
|
| 225 |
+
tag, real_text = m.group(1), m.group(2).strip()
|
| 226 |
+
voice = TAG_TO_VOICE.get(tag)
|
| 227 |
+
if not voice or not real_text or real_text.startswith("⚠️"):
|
| 228 |
+
return gr.update()
|
| 229 |
+
|
| 230 |
+
audio_file = generate_tts_sync(real_text, voice)
|
| 231 |
+
if audio_file is None:
|
| 232 |
+
return gr.update()
|
| 233 |
+
|
| 234 |
+
return audio_file
|
| 235 |
+
|
| 236 |
# ---------------------------------------------------------------------------
|
| 237 |
# 6. Gradio 界面设计 (支持源语重放 + 灵活切换目的语)
|
| 238 |
# ---------------------------------------------------------------------------
|
|
|
|
| 312 |
outputs=[chatbot, audio_out]
|
| 313 |
)
|
| 314 |
|
| 315 |
+
# 5- 点击历史记录中的任意气泡,重新合成并播放该条文字的语音
|
| 316 |
+
chatbot.select(
|
| 317 |
+
fn=on_history_select,
|
| 318 |
+
inputs=None,
|
| 319 |
+
outputs=[audio_out]
|
| 320 |
+
)
|
| 321 |
+
|
| 322 |
if __name__ == "__main__":
|
| 323 |
port = int(os.environ.get("PORT", 7860))
|
| 324 |
demo.queue().launch(
|