6.5 KiB
6.5 KiB
语音播放问题排查指南
🔍 问题现象
后端成功生成了 AI 语音(120463 字节),但前端没有播放出来。
📋 排查步骤
1. 检查前端是否收到音频数据
重新编译并运行,查看前端控制台日志:
✅ 对话响应: ...
✅ 识别结果: ghost~来啦?
✅ AI回复: ghost~来啦?刚在有《夏日友人帐》...
✅ 音频数据: XXXXX 字符 <-- 应该看到这行
🔊 开始播放 AI 语音回复...
🔊 音频数据前100字符: ...
如果没有看到"音频数据":
- 问题在后端返回数据格式
- 检查后端响应结构
如果看到了"音频数据":
- 继续下一步
2. 检查 playAIVoice 是否被调用
查看日志:
🔊 playAIVoice 被调用
🔊 base64Audio 长度: XXXXX
🔊 aiText: ...
📦 开始解码 base64...
✅ 音频数据解码完成,大小: XXXXX bytes
📱 APP 环境,保存并播放音频
如果没有看到这些日志:
playAIVoice没有被调用- 检查
audioData是否为空
如果看到了这些日志:
- 继续下一步
3. 检查文件保存是否成功
查看日志:
✅ 获取 _doc 目录成功
✅ 创建文件成功: ai_voice_xxx.mp3
✅ 文件写入成功
📁 文件路径: /storage/emulated/0/Android/data/...
如果看到错误:
- 文件系统权限问题
- 检查 APP 存储权限
如果文件保存成功:
- 继续下一步
4. 检查音频播放
查看日志:
🎵 创建音频上下文...
🎵 设置音频源: /storage/emulated/0/Android/data/.../ai_voice_xxx.mp3
🔊 AI 语音开始播放 <-- 应该看到这行
如果看到播放错误:
- 音频格式问题
- 音频文件损坏
- 播放器不支持
🔧 常见问题和解决方案
问题 1:没有收到音频数据
症状:
✅ AI回复: ...
⚠️ 没有收到音频数据
原因:
- 后端返回数据格式不正确
audio_data字段缺失
解决方案:
检查后端响应:
# 使用 curl 测试
curl -X POST http://127.0.0.1:30101/voice/call/conversation \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"audio_data":"...","format":"wav"}' \
| jq '.data.audio_data' | head -c 100
应该看到 base64 字符串。
问题 2:base64 解码失败
症状:
❌ 播放 AI 语音失败
错误类型: InvalidCharacterError
原因:
- base64 字符串包含非法字符
- 字符串被截断
解决方案:
检查 base64 字符串:
console.log('base64 前10字符:', audioData.substring(0, 10))
console.log('base64 后10字符:', audioData.substring(audioData.length - 10))
console.log('是否包含非法字符:', /[^A-Za-z0-9+/=]/.test(audioData))
问题 3:文件保存失败
症状:
❌ 获取文件系统失败
❌ 创建文件失败
原因:
- APP 没有存储权限
- 文件路径不存在
解决方案:
- 检查 APP 权限:
// 在 manifest.json 中添加
"permissions": {
"android.permission.WRITE_EXTERNAL_STORAGE": {},
"android.permission.READ_EXTERNAL_STORAGE": {}
}
- 使用其他目录:
// 尝试使用 _downloads 目录
plus.io.resolveLocalFileSystemURL('_downloads/', ...)
问题 4:音频播放失败
症状:
✅ 文件写入成功
🎵 设置音频源: ...
❌ 播放失败: {errMsg: "..."}
原因:
- 音频格式不支持
- 文件路径错误
- 音频文件损坏
解决方案:
- 验证音频文件:
// 检查文件是否存在
plus.io.resolveLocalFileSystemURL(filePath, (entry) => {
entry.file((file) => {
console.log('文件大小:', file.size)
console.log('文件类型:', file.type)
})
})
- 使用绝对路径:
// 使用 fileEntry.toLocalURL()
const audioUrl = fileEntry.toLocalURL()
audioContext.src = audioUrl
- 测试音频文件:
// 保存到相册,手动播放测试
plus.gallery.save(filePath, () => {
console.log('已保存到相册,请手动播放测试')
})
🎯 调试技巧
1. 保存音频文件到相册
// 在 playAIVoice 中添加
writer.onwrite = () => {
console.log('✅ 文件写入成功')
// 保存到相册以便测试
plus.gallery.save(fileEntry.fullPath, () => {
console.log('✅ 已保存到相册')
uni.showToast({
title: '音频已保存到相册',
icon: 'none'
})
}, (error) => {
console.error('保存到相册失败:', error)
})
// 继续播放...
}
2. 使用系统播放器测试
// 使用系统播放器打开
plus.runtime.openFile(fileEntry.fullPath, {}, (error) => {
console.error('打开文件失败:', error)
})
3. 对比文件大小
console.log('原始 base64 长度:', base64Audio.length)
console.log('解码后字节数:', bytes.length)
console.log('预期字节数:', Math.ceil(base64Audio.length * 3 / 4))
console.log('后端返回大小:', 120463) // 从后端日志获取
应该接近 120463 字节。
📝 完整的调试日志示例
成功的日志:
📤 发送语音对话请求...
✅ 对话响应: {statusCode: 200, data: {...}}
✅ 识别结果: ghost~来啦?
✅ AI回复: ghost~来啦?刚在有《夏日友人帐》...
✅ 音频数据: 160616 字符
🔊 开始播放 AI 语音回复...
🔊 音频数据前100字符: SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjYxLjEuMTAwAAAAAAAAAAAAAAD/+5DEAAAAAAAAAAAAAAAAAAAAAABJbmZvAAAADwAAAA...
🔊 playAIVoice 被调用
🔊 base64Audio 长度: 160616
🔊 aiText: ghost~来啦?刚在有《夏日友人帐》...
📦 开始解码 base64...
✅ 音频数据解码完成,大小: 120463 bytes
📱 APP 环境,保存并播放音频
✅ 获取 _doc 目录成功
✅ 创建文件成功: ai_voice_1709636448745.mp3
📝 开始写入文件...
✅ 文件写入成功
📁 文件路径: /storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/doc/ai_voice_1709636448745.mp3
🎵 创建音频上下文...
🎵 设置音频源: /storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/doc/ai_voice_1709636448745.mp3
🔊 AI 语音开始播放
✅ AI 语音播放完成
🗑️ 临时文件已清理
🚀 下一步
如果以上步骤都无法解决问题,请提供:
- 完整的前端控制台日志
- 后端日志(TTS 合成部分)
- 设备信息(Android 版本、APP 版本)
- 是否有其他音频播放功能正常工作
最后更新: 2026-03-05