diff --git a/app/entry/src/main/ets/components/f4/TtsEngine.ets b/app/entry/src/main/ets/components/f4/TtsEngine.ets index 0159ebb..bac4735 100644 --- a/app/entry/src/main/ets/components/f4/TtsEngine.ets +++ b/app/entry/src/main/ets/components/f4/TtsEngine.ets @@ -8,6 +8,8 @@ * - 不依赖 queueMode:官方 API 文档(0=flush)与 Codelabs(0=排队)说法 * 互相矛盾,新朗读前显式 engine.stop() 打断,语义自持 * - 播报状态回调 onStateChanged:页面据此复位 🔊 图标 + * - V3:speak 前 sanitizeForSpeech 净化——不念 Markdown/英文标点/表情符号 + * (中文停顿标点保留做自然停顿) * * 模型:offline 中文引擎(online: 1,系统内置);模拟器通常无此服务,须真机。 * 日志 tag MEIDA_TTS:hdc shell hilog | grep MEIDA_TTS @@ -18,6 +20,18 @@ import { textToSpeech } from '@kit.CoreSpeechKit' const SEGMENT_MAX_CHARS: number = 400 const SEGMENT_FALLBACK_MS: number = 150000 +/** + * 朗读净化(V3):剥掉会被引擎念出来的符号——Markdown 标记(**、#、- 列表符)、 + * 英文标点、表情等,只留中英文、数字与中文停顿标点(,。;:!?、……靠它们做自然停顿, + * 引擎不会逐字念)。顾问回答被要求不写 Markdown(agent_chat v1),这里是双保险。 + */ +function sanitizeForSpeech(text: string): string { + return text + .replace(/[^一-龥a-zA-Z0-9\s。,、;:!?]/g, ' ') + .replace(/\s+/g, ' ') + .trim() +} + /** 播报状态变化回调(speaking=false 表示本轮朗读完全结束或被停止)。 */ export type TtsStateChanged = (speaking: boolean) => void @@ -78,7 +92,7 @@ export class TtsEngine { * 由调用方决定是否提示(自动朗读静默、手动点击提示)。 */ async speak(text: string): Promise { - const trimmed: string = text.trim() + const trimmed: string = sanitizeForSpeech(text) if (trimmed.length === 0) { return }