From 4d71363fadb590f902da296d4c6acfac7f3fd8f6 Mon Sep 17 00:00:00 2001 From: Lilixu007 <1273914445@qq.com> Date: Thu, 5 Mar 2026 18:31:52 +0800 Subject: [PATCH] =?UTF-8?q?TTS=E6=96=87=E4=BB=B6=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- xuniYou/pages/chat/phone.vue | 148 ++++++++++++++++++++++++----------- 1 file changed, 101 insertions(+), 47 deletions(-) diff --git a/xuniYou/pages/chat/phone.vue b/xuniYou/pages/chat/phone.vue index 7ae1284..c6747b8 100644 --- a/xuniYou/pages/chat/phone.vue +++ b/xuniYou/pages/chat/phone.vue @@ -1397,80 +1397,134 @@ console.log('✅ 音频数据解码完成,大小:', bytes.length, 'bytes') // #ifdef APP-PLUS - // APP 环境 - 简化实现 - console.log('📱 APP 环境,保存并播放音频') + // APP 环境 - 使用 plus.io 写入文件 + console.log('📱 APP 环境,保存音频文件') + console.log('📊 音频数据大小:', bytes.length, 'bytes') const fileName = `ai_voice_${Date.now()}.mp3` - const filePath = `_doc/${fileName}` // 使用 plus.io 保存文件 - plus.io.resolveLocalFileSystemURL('_doc/', (entry) => { + plus.io.resolveLocalFileSystemURL('_doc/', (docEntry) => { console.log('✅ 获取 _doc 目录成功') - entry.getFile(fileName, {create: true}, (fileEntry) => { - console.log('✅ 创建文件成功:', fileName) + docEntry.getFile(fileName, {create: true, exclusive: false}, (fileEntry) => { + console.log('✅ 文件对象创建成功') + console.log('📁 文件路径:', fileEntry.fullPath) + // 创建 FileWriter fileEntry.createWriter((writer) => { - writer.onwrite = () => { - console.log('✅ 文件写入成功') - console.log('📁 文件路径:', fileEntry.fullPath) + console.log('✅ FileWriter 创建成功') + + // 设置写入完成事件 + writer.onwriteend = function(evt) { + console.log('✅✅✅ 文件写入完成!') - // 播放音频 - console.log('🎵 创建音频上下文...') - const audioContext = uni.createInnerAudioContext() - - // 使用完整路径 - const fullPath = fileEntry.fullPath - console.log('🎵 设置音频源:', fullPath) - audioContext.src = fullPath - audioContext.autoplay = true - - audioContext.onPlay(() => { - console.log('🔊 AI 语音开始播放') - }) - - audioContext.onEnded(() => { - console.log('✅ AI 语音播放完成') - // 清理 - audioContext.destroy() - fileEntry.remove(() => { - console.log('🗑️ 临时文件已清理') + // 验证文件大小 + fileEntry.file((file) => { + console.log('📊 文件大小:', file.size, 'bytes') + + if (file.size === 0) { + console.error('❌ 文件大小为 0') + uni.showToast({ + title: '文件保存失败', + icon: 'none' + }) + return + } + + // 获取文件 URL + const audioUrl = fileEntry.toLocalURL() + console.log('🎵 准备播放,URL:', audioUrl) + + // 使用 plus.audio 播放 + console.log('🎵 创建播放器...') + const player = plus.audio.createPlayer(audioUrl) + + player.play(() => { + console.log('🔊🔊🔊 AI 语音开始播放!') + uni.showToast({ + title: 'AI 正在说话', + icon: 'none', + duration: 1000 + }) + }, (e) => { + console.error('❌ plus.audio 播放失败:', e) + console.error('错误详情:', JSON.stringify(e)) + + // 如果 plus.audio 失败,尝试 uni.createInnerAudioContext + console.log('🔄 尝试使用 InnerAudioContext') + const ctx = uni.createInnerAudioContext() + ctx.src = audioUrl + ctx.autoplay = true + + ctx.onPlay(() => { + console.log('🔊 InnerAudioContext 播放成功') + uni.showToast({ + title: 'AI 正在说话', + icon: 'none' + }) + }) + + ctx.onError((err) => { + console.error('❌ InnerAudioContext 也失败:', err) + uni.showToast({ + title: '播放失败', + icon: 'none', + duration: 3000 + }) + }) + + ctx.onEnded(() => { + console.log('✅ 播放完成') + ctx.destroy() + // 清理文件 + fileEntry.remove(() => console.log('🗑️ 文件已清理')) + }) }) - }) - - audioContext.onError((error) => { - console.error('❌ 播放失败:', error) - console.error('错误详情:', JSON.stringify(error)) - uni.showToast({ - title: '播放失败', - icon: 'none' + + player.addEventListener('ended', () => { + console.log('✅ 播放完成') + player.close() + // 清理文件 + fileEntry.remove(() => console.log('🗑️ 文件已清理')) }) - audioContext.destroy() + + player.addEventListener('error', (e) => { + console.error('❌ 播放错误:', e) + player.close() + }) + + }, (error) => { + console.error('❌ 获取文件信息失败:', error) }) } - writer.onerror = (error) => { - console.error('❌ 文件写入失败:', error) + // 设置写入错误事件 + writer.onerror = function(e) { + console.error('❌❌❌ 文件写入失败!') + console.error('错误对象:', e) + uni.showToast({ title: '文件保存失败', icon: 'none' }) } - // 写入数据 - console.log('📝 开始写入文件...') - const blob = new Blob([bytes.buffer], {type: 'audio/mp3'}) - writer.write(blob) + // 直接写入 Uint8Array + console.log('📝 开始写入二进制数据...') + console.log('📝 数据大小:', bytes.length, 'bytes') + writer.write(bytes) + }, (error) => { - console.error('❌ 创建 writer 失败:', error) + console.error('❌ 创建 FileWriter 失败:', error) }) + }, (error) => { console.error('❌ 创建文件失败:', error) - console.error('错误详情:', JSON.stringify(error)) }) + }, (error) => { console.error('❌ 获取文件系统失败:', error) - console.error('错误详情:', JSON.stringify(error)) }) // #endif