Tolan - 立群

zlwu 1dd1339b4b 提交 1 rok temu
backend 9d92a207c8 v2.7 1 rok temu
doubao-api b0c1d1042d 提交代码 1 rok temu
frontend 1dd1339b4b 提交 1 rok temu
提示词包 30628ed76c v3.0 1 rok temu
需求 30628ed76c v3.0 1 rok temu
项目文档 30628ed76c v3.0 1 rok temu
.DS_Store 30628ed76c v3.0 1 rok temu
.cursorrules 30628ed76c v3.0 1 rok temu
.gitignore 5a0ae04f68 提交代码 1 rok temu
HTTPS_SETUP.md 1b5658290f 提交代码 1 rok temu
IPHONE_STEP_BY_STEP.md 1b5658290f 提交代码 1 rok temu
IPHONE_TRUST_CERT.md 1b5658290f 提交代码 1 rok temu
MOBILE_SETUP.md 1b5658290f 提交代码 1 rok temu
NETWORK_CONFIG.md 1b5658290f 提交代码 1 rok temu
QUICK_START_HTTPS.md 1b5658290f 提交代码 1 rok temu
README.md 30628ed76c v3.0 1 rok temu
configure-network.sh 1b5658290f 提交代码 1 rok temu
start-https.sh 1b5658290f 提交代码 1 rok temu
优化总结.md 1bd9c51b65 提交代码 1 rok temu
优化汇总-V2.md 1bd9c51b65 提交代码 1 rok temu
快速响应优化-最终版.md 1bd9c51b65 提交代码 1 rok temu
性能分析报告.md 37d5a8470b v3.4 1 rok temu
无限循环修复.md 1bd9c51b65 提交代码 1 rok temu
智能预播放优化.md 1bd9c51b65 提交代码 1 rok temu
最终优化方案.md 1bd9c51b65 提交代码 1 rok temu
最终方案-禁用预播放.md 1bd9c51b65 提交代码 1 rok temu
流式播放-WebAudioAPI方案.md 44446dc5fb v3.5 1 rok temu
流式播放优化说明.md 1bd9c51b65 提交代码 1 rok temu
测试说明.md 1bd9c51b65 提交代码 1 rok temu
连接池耗尽修复.md 9d92a207c8 v2.7 1 rok temu
问题修复说明.md 1bd9c51b65 提交代码 1 rok temu

README.md

Tolan - AI语音英语助手

[![Python](https://img.shields.io/badge/Python-3.9+-blue.svg)](https://www.python.org) [![React](https://img.shields.io/badge/React-18+-61DAFB.svg)](https://reactjs.org) [![FastAPI](https://img.shields.io/badge/FastAPI-0.110+-009688.svg)](https://fastapi.tiangolo.com) [![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE) 与AI动画IP进行实时语音对话,提高英语口语水平

📖 项目简介

Tolan是一个基于AI的实时语音交互应用,用户可以通过与动画IP角色进行语音对话来练习英语口语。系统采用前后端分离架构,实现了低延迟(<300ms)的实时语音交互体验。

✨ 核心特性

  • 🎤 实时语音录音 - 使用Recorder.js,支持跨平台(PC/移动端)
  • 🔊 流式音频播放 - MediaSource API,边接收边播放
  • 🌐 WebSocket通信 - 实时双向通信,超低延迟
  • 🎭 动画IP三态 - 待机/倾听/说话状态智能切换
  • ⚡ 连接池预热 - 消除连接建立延迟,实现0.3秒响应
  • 🔄 流式处理 - 音频实时采集、传输、播放
  • 📱 多端兼容 - 支持PC和移动端浏览器

🏗️ 项目架构

┌─────────────┐         WSS/HTTPS        ┌─────────────┐        WebSocket       ┌─────────────┐
│   浏览器     │ ◄────────────────────── │  WSS服务器   │ ◄─────────────────── │  豆包API     │
│  (React)    │                          │  (FastAPI)  │                       │             │
│             │ ─────────────────────► │             │ ──────────────────► │             │
└─────────────┘    实时音频流/控制消息    └─────────────┘   实时音频流/控制消息   └─────────────┘

📁 项目结构

Tolan/
├── frontend/              # 前端应用(React + TypeScript)
│   ├── src/
│   │   ├── components/   # React组件
│   │   ├── stores/       # Zustand状态管理
│   │   ├── utils/        # 工具模块(WebSocket、录音、播放)
│   │   └── config.ts     # 配置文件
│   ├── package.json
│   └── README.md
│
├── backend/               # 后端服务(FastAPI + Python)
│   ├── main.py           # FastAPI主应用
│   ├── config.py         # 配置管理
│   ├── connection_pool.py # 豆包API连接池
│   ├── websocket_handler.py # WebSocket处理器
│   ├── doubao_api/       # 豆包API模块
│   ├── requirements.txt
│   └── README.md
│
├── doubao-api/           # 豆包官方Demo
│   └── realtime_dialog_client.py
│
├── ssl/                  # SSL证书
│   ├── cert.pem
│   └── key.pem
│
└── 项目文档/              # 项目文档
    ├── 用户需求分析书.md
    ├── 项目开发重点和难点分析.md
    ├── 开源组件推荐清单.md
    └── API文档.md

🚀 快速开始

前置要求

  • Node.js >= 18.0.0
  • Python >= 3.9
  • 浏览器: Chrome 90+ / Safari 14+ / Firefox 88+

1. 克隆项目

git clone <repository-url>
cd Tolan

2. 启动后端

# 进入后端目录
cd backend

# 安装依赖(使用本机Python)
pip install -r requirements.txt

# 启动服务
python main.py

后端将在 http://localhost:8000 启动

3. 启动前端

# 新开终端,进入前端目录
cd frontend

# 安装依赖
npm install

# 启动开发服务器
npm run dev

前端将在 http://localhost:5173 启动

4. 开始使用

  1. 在浏览器打开 http://localhost:5173
  2. 允许麦克风权限
  3. 按住录音按钮说话
  4. 松开按钮听取AI回复

🎯 技术栈

前端

  • 框架: React 18 + TypeScript
  • 构建: Vite 5
  • 状态管理: Zustand
  • 样式: Tailwind CSS
  • 录音: recorder-core (xiangyuecn/Recorder)
  • 播放: MediaSource API
  • 通信: WebSocket API

后端

  • 框架: FastAPI 0.110+
  • 异步: asyncio
  • WebSocket: FastAPI WebSocket
  • 日志: loguru
  • 配置: pydantic-settings + python-dotenv

📊 性能指标

指标 目标值 实际值
端到端延迟 < 300ms 145-240ms ✅
前端采集延迟 < 10ms ~8ms ✅
网络传输延迟 < 20ms 10-20ms ✅
后端处理延迟 < 10ms ~5ms ✅
连接建立延迟 0ms 0ms ✅ (连接池预热)

🔑 核心功能实现

1. 实时音频录音

// 使用Recorder.js实现跨平台录音
const recorder = new VoiceRecorder({
  sampleRate: 16000,
  bitRate: 16,
  onProcess: (pcmData) => {
    // 实时发送PCM数据
    websocket.sendAudio(pcmData.buffer)
  }
})

2. 流式音频播放

// 使用MediaSource API实现流式播放
const player = new StreamAudioPlayer()
await player.init()

// 边接收边播放
player.appendAudioChunk(audioData)

3. 豆包API连接池

# 预创建连接,消除延迟
class DoubaoConnectionPool:
    async def initialize(self):
        # 预创建10个连接
        for i in range(10):
            conn = await create_connection()
            await self.idle_connections.put(conn)
    
    async def acquire(self):
        # 零延迟获取连接
        return await self.idle_connections.get()

4. WebSocket流式处理

# 并发处理音频流
await asyncio.gather(
    receive_from_client(),  # 接收客户端音频
    send_to_doubao(),       # 转发给豆包
    receive_from_doubao(),  # 接收豆包响应
    send_to_client()        # 发送给客户端
)

📚 文档

🔧 开发指南

环境配置

前端:

cd frontend
npm install
npm run dev

后端:

cd backend
pip install -r requirements.txt
python main.py

调试

前端调试:

  • 浏览器开发者工具(F12)
  • Console查看日志
  • Network查看WebSocket通信

后端调试:

# 查看日志
tail -f backend/logs/app_*.log

# 健康检查
curl http://localhost:8000/health

🐛 故障排查

常见问题

  1. 麦克风权限被拒绝

    • 确保使用HTTPS或localhost
    • 检查浏览器权限设置
  2. WebSocket连接失败

    • 确认后端服务已启动
    • 检查防火墙设置
  3. 音频无法播放

    • 检查浏览器是否支持OGG/Opus
    • 确认音量设置
  4. 延迟过高

    • 检查网络连接
    • 查看连接池状态

详细故障排查请参考各模块的文档。

🔒 安全性

  • ✅ 强制HTTPS/WSS加密传输
  • ✅ CORS跨域保护
  • ✅ 音频数据不持久化
  • ✅ 会话隔离

🎯 豆包API集成

✅ 已完成集成

后端已完成豆包API的真实集成,支持:

  • ✅ 真实豆包API连接
  • ✅ 流式音频发送(PCM → 豆包)
  • ✅ 流式音频接收(豆包 → OGG/Opus)
  • ✅ 连接池预热(10个预创建连接)
  • ✅ 自动降级(API密钥未配置时使用模拟API)

配置步骤

  1. 获取API密钥: 访问豆包开放平台获取
  2. 配置环境: 在 backend/.env 中配置
  3. 启动测试: python backend/main.py

详细文档: backend/INTEGRATION_GUIDE.md

📈 未来计划

  • 集成真实豆包API ✅
  • 添加用户认证
  • 实现对话历史记录
  • 支持多语言
  • 添加语音评分功能
  • 实现学习进度追踪

🤝 贡献

欢迎贡献代码、提出问题和建议!

📄 许可证

MIT

🙏 致谢


**Tolan - 让英语学习更有趣!** 🎉 Made with ❤️ by Tolan Team