From a3bc821bc3fd0d226d40b192fbcd0136da43a4f8 Mon Sep 17 00:00:00 2001 From: francis_fh <13935151924@163.com> Date: Sat, 24 Jan 2026 18:29:47 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B5=81=E5=BC=8F=E6=95=B0=E6=8D=AE=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=E4=BC=98=E5=8C=96=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hook/useTTSPlayer.js | 13 +++----- pages/chat/components/ai-paging.vue | 52 +++++++++++++++++++++-------- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/hook/useTTSPlayer.js b/hook/useTTSPlayer.js index b8f4b99..9f95f3b 100644 --- a/hook/useTTSPlayer.js +++ b/hook/useTTSPlayer.js @@ -376,8 +376,7 @@ class TTSPlayer { // 微信小程序环境,使用背景音频管理器 const isBackgroundAudioAvailable = this.initAudioManager() - // 重置音频状态 - this.isSpeaking.value = true + // 重置音频状态,但不立即设置为正在播放,等待实际播放时再设置 this.isPaused.value = false this.isComplete.value = false @@ -391,7 +390,7 @@ class TTSPlayer { // 直接设置src并播放 this.backgroundAudioManager.src = url - console.log('🎵 微信小程序背景音频开始播放'); + console.log('🎵 微信小程序背景音频开始加载'); } else { // 降级方案:使用InnerAudioContext console.log('🔄 微信小程序:背景音频不可用,降级使用InnerAudioContext'); @@ -403,7 +402,7 @@ class TTSPlayer { } this.innerAudioContext = uni.createInnerAudioContext() - this.innerAudioContext.autoplay = false + this.innerAudioContext.autoplay = true // 设置自动播放,等音频加载完成后自动开始 this.innerAudioContext.obeyMuteSwitch = false this.innerAudioContext.volume = 1.0 @@ -438,13 +437,11 @@ class TTSPlayer { this.innerAudioContext.onCanplay(() => { console.log('🎵 微信小程序InnerAudioContext可以播放了') - if (this.isSpeaking.value && !this.isPaused.value) { - this.innerAudioContext.play() - } + // 不需要手动调用play,因为已经设置了autoplay }) this.innerAudioContext.src = url - console.log('🎵 微信小程序InnerAudioContext开始播放'); + console.log('🎵 微信小程序InnerAudioContext开始加载'); } // #endif diff --git a/pages/chat/components/ai-paging.vue b/pages/chat/components/ai-paging.vue index af01b9a..24352c0 100644 --- a/pages/chat/components/ai-paging.vue +++ b/pages/chat/components/ai-paging.vue @@ -479,11 +479,16 @@ const sendMessage = (text) => { console.log('📝 Has job info:', hasJobInfo); // 开始朗读当前消息 - speechIndex.value = index; - readMarkdown(message.displayText, index); + speechIndex.value = index; + readMarkdown(message.displayText, index, { immediate: false }); + // 一旦开始朗读,就设置speechIndex,避免重复调用 + speechIndex.value = index; } else { console.log('⏳ Waiting for more content before TTS, current length:', message.displayText.length); } + } else { + // 已经开始朗读这条消息,不再重复调用 + console.log('⏭️ Already speaking this message, skipping duplicate TTS call'); } } }, @@ -508,7 +513,7 @@ const sendMessage = (text) => { // 开始朗读完整的内容 speechIndex.value = lastMessageIndex; - readMarkdown(lastMessage.displayText, lastMessageIndex); + readMarkdown(lastMessage.displayText, lastMessageIndex, { immediate: true }); } } }, @@ -781,7 +786,10 @@ function confirmFeeBack(value) { // 防抖定时器 let ttsDebounceTimer = null; -function readMarkdown(value, index) { +// 保存上一次调用的文本内容,避免重复调用TTS +let lastSpeechText = ''; + +function readMarkdown(value, index, options = {}) { console.log('🎤 readMarkdown called'); console.log('📝 Text to speak:', value ? value.substring(0, 100) + '...' : 'No text'); console.log('🔢 Index:', index); @@ -798,17 +806,33 @@ function readMarkdown(value, index) { console.log('🛑 Always stopping current speech before starting new one'); speechIndex.value = index; - // 使用防抖,避免频繁调用TTS - ttsDebounceTimer = setTimeout(() => { - console.log('🎵 Starting new speech'); - console.log('🎵 Calling speak function with text length:', value ? value.length : 0); - try { - speak(value); - console.log('✅ Speak function called successfully'); - } catch (error) { - console.error('❌ Error calling speak function:', error); + // 立即调用speak,不使用防抖延迟 + const speakNow = () => { + // 检查文本内容是否发生变化,避免重复调用TTS + if (value !== lastSpeechText) { + console.log('🎵 Starting new speech'); + console.log('🎵 Calling speak function with text length:', value ? value.length : 0); + try { + speak(value); + console.log('✅ Speak function called successfully'); + // 更新上一次调用的文本内容 + lastSpeechText = value; + } catch (error) { + console.error('❌ Error calling speak function:', error); + } + } else { + console.log('🔄 Same text as last speech, skipping duplicate TTS call'); } - }, 300); // 300ms防抖延迟 + }; + + // 改进防抖逻辑,确保在短时间内只调用一次 + if (options.immediate) { + // 如果是onComplete回调,立即播放 + speakNow(); + } else { + // 对于流式数据,总是使用防抖,避免频繁调用 + ttsDebounceTimer = setTimeout(speakNow, 500); // 延长防抖时间到500ms + } } function stopMarkdown(value, index) { console.log('⏸️ stopMarkdown called for index:', index);