diff --git a/hook/useAudioSpeak.js b/hook/useAudioSpeak.js index cbe566f..5678937 100644 --- a/hook/useAudioSpeak.js +++ b/hook/useAudioSpeak.js @@ -110,20 +110,20 @@ export const useAudioSpeak = (config = {}) => { */ const _smartSplit = (text) => { if (!text || typeof text !== 'string') return []; - + const cleanText = text.replace(/\s+/g, ' ').trim(); if (!cleanText) return []; - + const segments = []; - + // 1. 按完整标点分割成独立的句子(包括中英文标点) // 正则解释:匹配非标点字符 + 标点符号(或者匹配到结尾) const sentenceRegex = /([^。?!;,、\n\r\.\?!;,]+[。?!;,、\n\r\.\?!;,]+|.+$)/g; - + let currentIndex = 0; let match; const rawSentences = []; - + while ((match = sentenceRegex.exec(cleanText)) !== null) { const sentence = match[0].trim(); if (sentence) { @@ -131,7 +131,7 @@ export const useAudioSpeak = (config = {}) => { } currentIndex = match.index + match[0].length; } - + // 处理最后剩余的部分 if (currentIndex < cleanText.length) { const remaining = cleanText.substring(currentIndex).trim(); @@ -139,12 +139,12 @@ export const useAudioSpeak = (config = {}) => { rawSentences.push(remaining); } } - + // 如果正则没有匹配到,整个文本作为一句话 if (rawSentences.length === 0) { rawSentences.push(cleanText); } - + // 2. 处理每个句子 for (const sentence of rawSentences) { if (sentence.length <= maxSegmentLength) { @@ -152,17 +152,17 @@ export const useAudioSpeak = (config = {}) => { segments.push(sentence); } else { // 句子超长,需要分割 - console.log('检测到超长句子,需要分割:', sentence); - + // console.log('检测到超长句子,需要分割:', sentence); + let currentPos = 0; const sentenceLength = sentence.length; - + while (currentPos < sentenceLength) { // 优先在标点处分割 let splitPos = -1; const searchStart = currentPos; const searchEnd = Math.min(currentPos + maxSegmentLength, sentenceLength); - + // 在搜索范围内找标点 for (let i = searchEnd - 1; i > searchStart; i--) { if (/[。?!;,、\n\r\.\?!;,]/u.test(sentence[i])) { @@ -170,32 +170,32 @@ export const useAudioSpeak = (config = {}) => { break; } } - + // 如果没找到标点,在最大限制处分割 if (splitPos === -1) { splitPos = searchEnd; } - + // 确保至少分割出一个字符 if (splitPos <= currentPos) { splitPos = currentPos + 1; } - + const segment = sentence.substring(currentPos, splitPos).trim(); if (segment) { segments.push(segment); } - + currentPos = splitPos; } } } - + // 3. 特殊情况:合并以冒号开头的短片段到上一句 const finalSegments = []; for (let i = 0; i < segments.length; i++) { const currentSegment = segments[i]; - + // 检查是否以冒号开头且很短(可能是被错误分割的部分) if (i > 0 && (currentSegment.startsWith(':') || currentSegment.startsWith(':')) && @@ -215,7 +215,7 @@ export const useAudioSpeak = (config = {}) => { finalSegments.push(currentSegment); } } - + // 清理:移除空白和空字符串 return finalSegments.filter(seg => seg && seg.trim()); } @@ -247,7 +247,7 @@ export const useAudioSpeak = (config = {}) => { */ const _fetchAudioWithRetry = async (text, retries = 0) => { try { - console.log(`📶正在请求音频: "${text}"`); + // console.log(`📶正在请求音频: "${text}"`); let Authorization = ''; if (useUserStore().token) { @@ -272,14 +272,14 @@ export const useAudioSpeak = (config = {}) => { throw new Error('音频数据太小或无效'); } - console.log(`音频获取成功,大小: ${audioBlob.size} 字节`); + // console.log(`音频获取成功,大小: ${audioBlob.size} 字节`); // 创建Blob URL return URL.createObjectURL(audioBlob); } catch (e) { if (retries < maxRetry) { - console.warn(`重试 ${retries + 1} 次,文本: ${text.substring(0, 10)}...`); + // console.warn(`重试 ${retries + 1} 次,文本: ${text.substring(0, 10)}...`); return await _fetchAudioWithRetry(text, retries + 1); } throw e; @@ -312,7 +312,7 @@ export const useAudioSpeak = (config = {}) => { index: textItem.index }); - console.log(`音频已添加到队列,当前队列长度: ${audioQueue.length}`); + // console.log(`音频已添加到队列,当前队列长度: ${audioQueue.length}`); // 如果当前因为没音频卡住了(Loading状态),立即尝试播放下一段 if (!audioSource && !isPaused.value && isPlaying) { @@ -334,7 +334,7 @@ export const useAudioSpeak = (config = {}) => { const initAudioContext = () => { if (!audioContext || audioContext.state === 'closed') { audioContext = new (window.AudioContext || window.webkitAudioContext)(); - console.log('音频上下文已初始化'); + // console.log('音频上下文已初始化'); } return audioContext; } @@ -355,7 +355,7 @@ export const useAudioSpeak = (config = {}) => { if (itemIndex === -1) { if (textQueue.length === 0 && !isFetching) { // 彻底播完了 - console.log('所有音频播放完成'); + // console.log('所有音频播放完成'); stopAudio(); _updateState({ isPlaying: false, msg: '播放结束' }); } else { @@ -427,7 +427,7 @@ export const useAudioSpeak = (config = {}) => { audioSource.connect(audioContext.destination); audioSource.onended = () => { - console.log(`第${index + 1}个片段播放完成`); + // console.log(`第${index + 1}个片段播放完成`); audioSource = null; // 播放下一段 @@ -495,7 +495,7 @@ export const useAudioSpeak = (config = {}) => { * 核心入口:开始播放长文本 */ const speak = async (text) => { - console.log('开始新的语音播报'); + // console.log('开始新的语音播报'); cleanup(); @@ -504,7 +504,7 @@ export const useAudioSpeak = (config = {}) => { text = extractSpeechText(text); - console.log('开始语音播报:', text); + // console.log('开始语音播报:', text); // 重置状态 isPlaying = true; @@ -529,7 +529,7 @@ export const useAudioSpeak = (config = {}) => { // 1. 智能切割文本 const segments = _smartSplit(text); - console.log('文本分段结果:', segments); + // console.log('文本分段结果:', segments); if (segments.length === 0) { console.warn('没有有效的文本可以播报'); @@ -599,7 +599,7 @@ export const useAudioSpeak = (config = {}) => { * 停止播放 */ const stopAudio = () => { - console.log('停止音频播放'); + // console.log('停止音频播放'); isPlaying = false; isPaused.value = false; @@ -611,7 +611,7 @@ export const useAudioSpeak = (config = {}) => { if (audioSource) { try { audioSource.stop(); - console.log('音频源已停止'); + // console.log('音频源已停止'); } catch (e) { console.warn('停止音频源失败:', e); } @@ -650,16 +650,16 @@ export const useAudioSpeak = (config = {}) => { * 清理资源 */ const cleanup = () => { - console.log('开始清理资源'); + // console.log('开始清理资源'); stopAudio(); if (audioContext && audioContext.state !== 'closed') { audioContext.close(); - console.log('音频上下文已关闭'); + // console.log('音频上下文已关闭'); } audioContext = null; - console.log('资源清理完成'); + // console.log('资源清理完成'); } return { diff --git a/hook/useRealtimeRecorderOnce.js b/hook/useRealtimeRecorderOnce.js index b0497bd..259c853 100644 --- a/hook/useRealtimeRecorderOnce.js +++ b/hook/useRealtimeRecorderOnce.js @@ -287,7 +287,7 @@ export function useRealtimeRecorderOnce() { source.connect(processor); processor.connect(audioContext.destination); - console.log('H5 16kHz WAV录音已启动'); + // console.log('H5 16kHz WAV录音已启动'); } catch (err) { console.error('H5录音启动失败:', err); @@ -336,7 +336,7 @@ export function useRealtimeRecorderOnce() { }); recorderManager.onStart(() => { - console.log('APP 16kHz WAV录音已开始'); + // console.log('APP 16kHz WAV录音已开始'); }); recorderManager.onError((err) => { @@ -373,7 +373,7 @@ export function useRealtimeRecorderOnce() { const cancelRecording = () => { if (!isRecording.value) return; - console.log('取消录音 - 丢弃结果'); + // console.log('取消录音 - 丢弃结果'); // 1. 停止硬件录音 stopHardwareResource(); @@ -506,7 +506,7 @@ export function useRealtimeRecorderOnce() { const wavBuffer = encodeWAV(mergedSamples, 16000, 1, 16); audioBlob = new Blob([wavBuffer], { type: 'audio/wav' }); - console.log(`H5生成WAV文件: ${audioBlob.size} bytes, 时长: ${mergedSamples.length / 16000}秒`); + // console.log(`H5生成WAV文件: ${audioBlob.size} bytes, 时长: ${mergedSamples.length / 16000}秒`); } // #endif @@ -534,7 +534,7 @@ export function useRealtimeRecorderOnce() { const wavBuffer = encodeWAV(floatSamples, 16000, 1, 16); audioBlob = new Blob([wavBuffer], { type: 'audio/wav' }); - console.log(`APP生成WAV文件: ${audioBlob.size} bytes, 时长: ${floatSamples.length / 16000}秒`); + // console.log(`APP生成WAV文件: ${audioBlob.size} bytes, 时长: ${floatSamples.length / 16000}秒`); } // #endif @@ -576,7 +576,7 @@ export function useRealtimeRecorderOnce() { a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); - console.log('WAV文件已保存用于调试'); + // console.log('WAV文件已保存用于调试'); } /** diff --git a/pages/chat/components/ai-paging.vue b/pages/chat/components/ai-paging.vue index f08608f..23a57dd 100644 --- a/pages/chat/components/ai-paging.vue +++ b/pages/chat/components/ai-paging.vue @@ -365,7 +365,7 @@ onMounted(async () => { }) onUnmounted(()=>{ - console.log('清理TTS资源') + // console.log('清理TTS资源') cleanup() })