开源组件推荐清单.md 28 KB

开源组件推荐清单

文档说明

本文档提供项目开发所需的开源组件推荐,所有组件均经过技术评估,符合项目的实时性、低延迟和兼容性要求。


0. 项目结构说明

0.1 代码目录

/Users/wuzilong/work/00code/Tolan/
├── frontend/              # 前端代码目录
│   ├── src/
│   │   ├── components/   # React组件
│   │   ├── utils/        # 工具函数
│   │   ├── hooks/        # 自定义Hooks
│   │   ├── stores/       # Zustand状态管理
│   │   └── assets/       # 静态资源
│   ├── public/
│   │   └── animations/   # Lottie动画文件
│   ├── package.json
│   └── vite.config.ts
│
├── backend/               # 后端代码目录
│   ├── main.py           # FastAPI主程序
│   ├── connection_pool.py # 豆包API连接池
│   ├── websocket_handler.py # WebSocket处理器
│   ├── config.py         # 配置管理
│   └── requirements.txt  # Python依赖
│
├── doubao-api/           # 豆包API集成
│   ├── realtime_dialog_client.py
│   └── protocol.py
│
├── ssl/                  # SSL证书
│   ├── cert.pem
│   └── key.pem
│
└── 项目文档/              # 项目文档

0.2 Python环境说明

重要:本项目使用本机Python环境,不需要创建虚拟环境。

# 检查Python版本(需要 >= 3.9)
python --version

# 直接使用 pip 安装依赖
pip install -r backend/requirements.txt

# 运行命令使用 python(不是 python3)
python -m uvicorn main:app --reload

1. 前端核心组件

1.1 开发框架

React 生态系统

组件 推荐版本 用途 选择理由
React 18.2+ 前端框架 Concurrent模式支持、优秀的性能、生态成熟
Vite 5.0+ 构建工具 极速开发体验、原生ESM、优化的生产构建
TypeScript 5.0+ 类型系统 类型安全、更好的IDE支持、减少运行时错误
# 前端项目初始化(在 frontend/ 目录)
cd /Users/wuzilong/work/00code/Tolan/frontend
npm create vite@latest . -- --template react-ts
npm install

1.2 音频处理 ⭐⭐⭐⭐⭐

录音组件(核心)

Recorder - xiangyuecn/Recorder

  • 版本: Latest
  • License: MIT
  • Star: 5.5k+
  • 用途: 跨平台音频录音

核心优势:

  • ✅ 多端兼容: 完美支持PC、Android、iOS各浏览器
  • ✅ 格式支持: 支持PCM、WAV、MP3等多种格式
  • ✅ 实时处理: 支持实时获取PCM数据
  • ✅ 体积小巧: 核心文件仅30KB
  • ✅ 文档完善: 中文文档详细,示例丰富

安装方式:

npm install recorder-core

基础使用:

import Recorder from 'recorder-core';
import 'recorder-core/src/engine/pcm'; // 引入PCM格式

// 创建录音实例
const rec = Recorder({
  type: "pcm",           // 输出PCM格式
  sampleRate: 16000,     // 采样率16kHz
  bitRate: 16,           // 位深16位
  onProcess: function(buffers, powerLevel, duration, sampleRate) {
    // 实时获取PCM数据
    const pcmData = Recorder.SampleData(buffers, sampleRate, 16000);
    
    // 转换为Int16格式
    const int16Data = new Int16Array(pcmData.data.length);
    for(let i = 0; i < pcmData.data.length; i++) {
      int16Data[i] = pcmData.data[i];
    }
    
    // 实时发送到后端
    websocket.send(int16Data.buffer);
  }
});

// 打开录音
rec.open(function() {
  // 开始录音
  rec.start();
}, function(msg, isUserNotAllow) {
  console.error('无法录音:', msg);
});

// 停止录音
rec.stop(function(blob, duration) {
  console.log('录音完成');
}, function(msg) {
  console.error('停止失败:', msg);
});

iOS兼容方案:

// iOS需要在用户交互中初始化
import Recorder from 'recorder-core';
import 'recorder-core/src/extensions/ios-weixin-config';

// iOS微信兼容
Recorder.IsOpen(function() {
  // 已准备好
}, function(msg, isUserNotAllow) {
  // 处理错误
});

音频播放组件

howler.js

  • 版本: 2.2.3+
  • License: MIT
  • Star: 23k+
  • 用途: 音频播放控制

核心优势:

  • ✅ 支持多种音频格式(包括OGG/Opus)
  • ✅ 跨浏览器兼容性好
  • ✅ 支持流式播放
  • ✅ 自动处理音频解锁(iOS)
npm install howler
import { Howl } from 'howler';

// 流式播放音频
const sound = new Howl({
  src: ['audio.ogg'], // 支持OGG格式
  format: ['ogg'],
  html5: true,        // 使用HTML5 Audio(支持流式)
  onload: function() {
    console.log('音频加载完成');
  },
  onplay: function() {
    console.log('开始播放');
  }
});

sound.play();

流式播放方案(实时音频):

由于Howler.js不直接支持流式追加,建议使用原生方案:

// 使用MediaSource API实现流式播放
class StreamAudioPlayer {
  constructor() {
    this.mediaSource = new MediaSource();
    this.audio = document.createElement('audio');
    this.audio.src = URL.createObjectURL(this.mediaSource);
    this.sourceBuffer = null;
    this.queue = [];
  }
  
  async init() {
    return new Promise((resolve) => {
      this.mediaSource.addEventListener('sourceopen', () => {
        this.sourceBuffer = this.mediaSource.addSourceBuffer('audio/ogg; codecs=opus');
        this.sourceBuffer.addEventListener('updateend', () => {
          if (this.queue.length > 0 && !this.sourceBuffer.updating) {
            this.sourceBuffer.appendBuffer(this.queue.shift());
          }
        });
        resolve();
      });
    });
  }
  
  appendAudio(chunk) {
    if (!this.sourceBuffer.updating) {
      this.sourceBuffer.appendBuffer(chunk);
    } else {
      this.queue.push(chunk);
    }
    
    if (this.audio.paused && this.sourceBuffer.buffered.length > 0) {
      this.audio.play();
    }
  }
}

1.3 WebSocket通信

Socket.IO Client (可选)

  • 版本: 4.6+
  • License: MIT
  • Star: 10k+
npm install socket.io-client

或使用原生WebSocket(推荐,更低延迟):

class RealtimeWebSocket {
  constructor(url) {
    this.url = url;
    this.ws = null;
    this.reconnectAttempts = 0;
    this.maxReconnectAttempts = 5;
  }
  
  connect() {
    this.ws = new WebSocket(this.url);
    this.ws.binaryType = 'arraybuffer'; // 二进制模式
    
    this.ws.onopen = () => {
      console.log('WebSocket连接成功');
      this.reconnectAttempts = 0;
    };
    
    this.ws.onmessage = (event) => {
      // 接收音频数据
      if (event.data instanceof ArrayBuffer) {
        this.onAudioData?.(event.data);
      }
    };
    
    this.ws.onclose = () => {
      this.handleReconnect();
    };
  }
  
  send(data) {
    if (this.ws?.readyState === WebSocket.OPEN) {
      this.ws.send(data);
    }
  }
  
  handleReconnect() {
    if (this.reconnectAttempts < this.maxReconnectAttempts) {
      const delay = 1000 * Math.pow(2, this.reconnectAttempts);
      setTimeout(() => {
        this.reconnectAttempts++;
        this.connect();
      }, delay);
    }
  }
}

1.4 状态管理

Zustand

  • 版本: 4.5+
  • License: MIT
  • Star: 45k+
  • 用途: 轻量级状态管理

选择理由:

  • ✅ 极简API,学习成本低
  • ✅ 无需Provider包裹
  • ✅ TypeScript支持好
  • ✅ 性能优秀,适合实时应用
npm install zustand
import { create } from 'zustand';

type AnimationState = 'IDLE' | 'LISTENING' | 'SPEAKING';

interface AppState {
  animationState: AnimationState;
  isRecording: boolean;
  isPlaying: boolean;
  
  setAnimationState: (state: AnimationState) => void;
  startRecording: () => void;
  stopRecording: () => void;
  startPlaying: () => void;
  stopPlaying: () => void;
}

const useAppStore = create<AppState>((set) => ({
  animationState: 'IDLE',
  isRecording: false,
  isPlaying: false,
  
  setAnimationState: (state) => set({ animationState: state }),
  
  startRecording: () => set({ 
    isRecording: true, 
    animationState: 'LISTENING' 
  }),
  
  stopRecording: () => set({ 
    isRecording: false 
  }),
  
  startPlaying: () => set({ 
    isPlaying: true, 
    animationState: 'SPEAKING' 
  }),
  
  stopPlaying: () => set({ 
    isPlaying: false, 
    animationState: 'IDLE' 
  })
}));

export default useAppStore;

1.5 动画

方案一:Lottie(推荐)

lottie-web

  • 版本: 5.12+
  • License: MIT
  • Star: 30k+
  • 用途: JSON动画播放
npm install lottie-web
import lottie from 'lottie-web';

class AnimationController {
  private animations: Record<string, any> = {};
  private currentState: string = 'idle';
  
  constructor(container: HTMLElement) {
    // 加载三种状态的动画
    this.animations.idle = lottie.loadAnimation({
      container: container,
      renderer: 'svg',
      loop: true,
      autoplay: false,
      path: '/animations/idle.json'
    });
    
    this.animations.listening = lottie.loadAnimation({
      container: container,
      renderer: 'svg',
      loop: true,
      autoplay: false,
      path: '/animations/listening.json'
    });
    
    this.animations.speaking = lottie.loadAnimation({
      container: container,
      renderer: 'svg',
      loop: true,
      autoplay: false,
      path: '/animations/speaking.json'
    });
  }
  
  setState(state: 'idle' | 'listening' | 'speaking') {
    this.animations[this.currentState].stop();
    this.animations[this.currentState].hide();
    
    this.currentState = state;
    this.animations[state].show();
    this.animations[state].play();
  }
}

方案二:Spine(高级动画)

@esotericsoftware/spine-player

  • 用途: 骨骼动画播放
  • 适用场景: 复杂的角色动画
npm install @esotericsoftware/spine-player

1.6 UI组件库

方案一:Tailwind CSS(推荐)

Tailwind CSS

  • 版本: 3.4+
  • 用途: 原子化CSS框架
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

方案二:Ant Design

Ant Design

  • 版本: 5.15+
  • 用途: 企业级UI组件库
npm install antd

1.7 工具库

lodash-es - 工具函数库

npm install lodash-es
npm install -D @types/lodash-es

dayjs - 日期处理(轻量级)

npm install dayjs

axios - HTTP客户端(如果需要REST API)

npm install axios

2. 后端核心组件

2.1 Web框架

FastAPI

  • 版本: 0.110+
  • License: MIT
  • Star: 70k+
  • 用途: 异步Web框架

核心优势:

  • ✅ 原生异步支持(asyncio)
  • ✅ 自动API文档生成
  • ✅ WebSocket支持
  • ✅ 高性能(基于Starlette和Pydantic)
  • ✅ 类型提示支持
# 后端环境配置(使用本机Python环境)
cd /Users/wuzilong/work/00code/Tolan/backend

# 安装依赖(使用本机Python)
pip install fastapi[all]
pip install uvicorn[standard]
from fastapi import FastAPI, WebSocket
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

# CORS配置
app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://yourdomain.com"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()
    
    try:
        while True:
            # 接收音频数据
            audio_data = await websocket.receive_bytes()
            
            # 处理音频...
            
            # 发送响应
            await websocket.send_bytes(response_data)
    except Exception as e:
        print(f"WebSocket错误: {e}")
    finally:
        await websocket.close()

2.2 WebSocket库

websockets

  • 版本: 12.0+
  • License: BSD
  • Star: 5k+
pip install websockets

或直接使用FastAPI的WebSocket支持(推荐)

2.3 异步处理

内置 asyncio(Python 3.9+自带)

import asyncio
from asyncio import Queue

class StreamingSession:
    def __init__(self):
        self.audio_queue = Queue()
        self.response_queue = Queue()
    
    async def process_stream(self):
        # 并发处理多个任务
        await asyncio.gather(
            self.receive_audio(),
            self.send_to_doubao(),
            self.receive_from_doubao(),
            self.send_to_client()
        )

2.4 音频处理

pydub

  • 版本: 0.25+
  • License: MIT
  • 用途: 音频格式转换(如果需要)
pip install pydub
# 需要安装ffmpeg
# macOS: brew install ffmpeg
# Ubuntu: sudo apt-get install ffmpeg

注意: 由于项目要求实时流式传输,音频转换应该在前端完成(Recorder已支持PCM输出),后端直接透传,无需pydub。

2.5 配置管理

python-dotenv

  • 版本: 1.0+
  • 用途: 环境变量管理
pip install python-dotenv
from dotenv import load_dotenv
import os

load_dotenv()

DOUBAO_API_KEY = os.getenv("DOUBAO_API_KEY")
DOUBAO_APP_ID = os.getenv("DOUBAO_APP_ID")

2.6 日志处理

loguru

  • 版本: 0.7+
  • License: MIT
  • 用途: 简化的日志库
pip install loguru
from loguru import logger

# 配置日志
logger.add("logs/app_{time}.log", rotation="500 MB", retention="10 days")

logger.info("WebSocket连接建立")
logger.error("豆包API调用失败: {error}", error=str(e))
logger.debug("延迟测量: {latency}ms", latency=latency)

2.7 HTTP客户端

httpx

  • 版本: 0.27+
  • License: BSD
  • 用途: 异步HTTP客户端
pip install httpx
import httpx

async def call_api():
    async with httpx.AsyncClient() as client:
        response = await client.post(
            "https://api.example.com/endpoint",
            json={"key": "value"}
        )
        return response.json()

3. 开发工具

3.1 代码质量

前端:

# ESLint + Prettier
npm install -D eslint prettier eslint-config-prettier
npm install -D @typescript-eslint/parser @typescript-eslint/eslint-plugin

后端:

# Black(代码格式化)
pip install black

# Flake8(代码检查)
pip install flake8

# MyPy(类型检查)
pip install mypy

3.2 测试框架

前端:

# Vitest(与Vite完美集成)
npm install -D vitest @vitest/ui
npm install -D @testing-library/react @testing-library/jest-dom

后端:

# Pytest
pip install pytest pytest-asyncio pytest-cov

3.3 性能监控

前端:

web-vitals

npm install web-vitals
import { onCLS, onFID, onFCP, onLCP, onTTFB } from 'web-vitals';

function sendToAnalytics(metric: any) {
  console.log(metric);
}

onCLS(sendToAnalytics);
onFID(sendToAnalytics);
onFCP(sendToAnalytics);
onLCP(sendToAnalytics);
onTTFB(sendToAnalytics);

自定义延迟监控:

class PerformanceTracker {
  private startTime: number = 0;
  
  start() {
    this.startTime = performance.now();
  }
  
  end(label: string) {
    const duration = performance.now() - this.startTime;
    console.log(`${label}: ${duration.toFixed(2)}ms`);
    
    // 发送到监控服务
    this.sendMetric(label, duration);
  }
  
  sendMetric(label: string, duration: number) {
    // 发送到后端或第三方监控服务
  }
}

4. 部署相关

4.1 容器化

Docker

前端Dockerfile:

FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 443
CMD ["nginx", "-g", "daemon off;"]

后端Dockerfile:

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

4.2 HTTPS/SSL

Let's Encrypt - 免费SSL证书

Certbot - 自动化SSL证书管理

# 安装Certbot
sudo apt-get install certbot python3-certbot-nginx

# 获取证书
sudo certbot --nginx -d yourdomain.com

或使用:

mkcert - 本地开发用证书

# 安装
brew install mkcert  # macOS
# 或
choco install mkcert  # Windows

# 创建本地证书
mkcert -install
mkcert localhost 127.0.0.1 ::1

4.3 反向代理

Nginx

配置示例(nginx.conf):

upstream backend {
    server localhost:8000;
}

server {
    listen 443 ssl http2;
    server_name yourdomain.com;
    
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    
    # 前端静态文件
    location / {
        root /usr/share/nginx/html;
        try_files $uri $uri/ /index.html;
    }
    
    # WebSocket代理
    location /ws {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_read_timeout 86400;
    }
}

5. 豆包API集成

5.1 官方SDK(如果有)

查阅豆包官方文档,使用官方Python SDK

5.2 自定义实现

基于项目中的 doubao-api/realtime_dialog_client.py

参考文件结构:

doubao-api/
├── realtime_dialog_client.py  # 豆包客户端
├── protocol.py                # 协议定义
├── config.py                  # 配置管理
└── audio_manager.py           # 音频管理

6. 推荐的依赖清单

6.1 前端 package.json

{
  "name": "tolan-frontend",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite --host",
    "build": "tsc && vite build",
    "preview": "vite preview",
    "test": "vitest",
    "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "recorder-core": "^1.2.23102400",
    "howler": "^2.2.3",
    "zustand": "^4.5.0",
    "lottie-web": "^5.12.2",
    "dayjs": "^1.11.10",
    "lodash-es": "^4.17.21"
  },
  "devDependencies": {
    "@types/react": "^18.2.55",
    "@types/react-dom": "^18.2.19",
    "@types/howler": "^2.2.11",
    "@types/lodash-es": "^4.17.12",
    "@typescript-eslint/eslint-plugin": "^6.21.0",
    "@typescript-eslint/parser": "^6.21.0",
    "@vitejs/plugin-react": "^4.2.1",
    "autoprefixer": "^10.4.17",
    "eslint": "^8.56.0",
    "eslint-config-prettier": "^9.1.0",
    "postcss": "^8.4.35",
    "prettier": "^3.2.5",
    "tailwindcss": "^3.4.1",
    "typescript": "^5.3.3",
    "vite": "^5.1.0",
    "vitest": "^1.2.2"
  }
}

6.2 后端 requirements.txt

# Web框架
fastapi==0.110.0
uvicorn[standard]==0.27.1

# WebSocket
websockets==12.0

# 异步HTTP客户端
httpx==0.27.0

# 配置管理
python-dotenv==1.0.1

# 日志
loguru==0.7.2

# 音频处理(可选,按需使用)
# pydub==0.25.1

# 开发工具
black==24.2.0
flake8==7.0.0
mypy==1.8.0

# 测试
pytest==8.0.1
pytest-asyncio==0.23.5
pytest-cov==4.1.0

# 类型提示
types-requests==2.31.0

7. 兼容性说明

7.1 Recorder 浏览器兼容性

浏览器 支持版本 说明
Chrome 53+ 完美支持
Firefox 52+ 完美支持
Safari 11+ 完美支持
Edge 79+ 完美支持(Chromium)
iOS Safari 11+ 需要用户交互激活,支持良好
Android Chrome 53+ 完美支持
微信浏览器 - 需要额外配置,支持良好

7.2 推荐的浏览器最低版本

  • Chrome/Edge: 90+
  • Firefox: 88+
  • Safari: 14+
  • iOS Safari: 14+
  • Android: 90+

8. 使用Recorder的完整示例

8.1 实时PCM流式传输

import Recorder from 'recorder-core';
import 'recorder-core/src/engine/pcm';

class VoiceRecorder {
  private recorder: any = null;
  private ws: WebSocket;
  
  constructor(websocketUrl: string) {
    this.ws = new WebSocket(websocketUrl);
    this.ws.binaryType = 'arraybuffer';
  }
  
  async init() {
    return new Promise<void>((resolve, reject) => {
      this.recorder = Recorder({
        type: 'pcm',
        sampleRate: 16000,
        bitRate: 16,
        
        // 实时回调,每隔一段时间触发
        onProcess: (buffers: any[], powerLevel: number, duration: number, sampleRate: number) => {
          // 获取PCM数据
          const pcmData = Recorder.SampleData(buffers, sampleRate, 16000);
          
          // 转换为Int16Array(小端序)
          const int16Data = new Int16Array(pcmData.data.length);
          for (let i = 0; i < pcmData.data.length; i++) {
            // Recorder内部是Int16,直接复制
            int16Data[i] = pcmData.data[i];
          }
          
          // 实时发送到WebSocket
          if (this.ws.readyState === WebSocket.OPEN) {
            this.ws.send(int16Data.buffer);
          }
        }
      });
      
      // 打开录音
      this.recorder.open(() => {
        console.log('录音已准备');
        resolve();
      }, (msg: string, isUserNotAllow: boolean) => {
        console.error('打开录音失败:', msg);
        reject(new Error(msg));
      });
    });
  }
  
  start() {
    if (this.recorder) {
      this.recorder.start();
      console.log('开始录音');
    }
  }
  
  stop() {
    return new Promise<void>((resolve) => {
      if (this.recorder) {
        this.recorder.stop(
          (blob: Blob, duration: number) => {
            console.log('录音完成,时长:', duration, 'ms');
            resolve();
          },
          (msg: string) => {
            console.error('停止录音失败:', msg);
            resolve();
          }
        );
      } else {
        resolve();
      }
    });
  }
  
  close() {
    if (this.recorder) {
      this.recorder.close();
    }
    if (this.ws) {
      this.ws.close();
    }
  }
}

// 使用示例
const recorder = new VoiceRecorder('wss://your-backend.com/ws');

// 初始化
await recorder.init();

// 按钮按下
button.addEventListener('mousedown', () => {
  recorder.start();
});

// 按钮松开
button.addEventListener('mouseup', async () => {
  await recorder.stop();
});

8.2 iOS兼容处理

import Recorder from 'recorder-core';
import 'recorder-core/src/extensions/ios-weixin-config';

// iOS需要在用户手势中初始化
class IOSCompatibleRecorder {
  private static isIOS = /iPhone|iPad|iPod/i.test(navigator.userAgent);
  private static isReady = false;
  
  static async prepare() {
    if (!this.isIOS || this.isReady) return;
    
    return new Promise<void>((resolve, reject) => {
      // iOS必须在用户交互中调用
      Recorder.IsOpen(() => {
        this.isReady = true;
        console.log('iOS录音已准备');
        resolve();
      }, (msg: string) => {
        console.error('iOS录音准备失败:', msg);
        reject(new Error(msg));
      });
    });
  }
}

// 在页面加载时显示提示
if (/iPhone|iPad|iPod/i.test(navigator.userAgent)) {
  // 显示"点击任意位置激活录音"的提示
  document.addEventListener('click', async () => {
    await IOSCompatibleRecorder.prepare();
    // 隐藏提示
  }, { once: true });
}

9. 性能优化建议

9.1 前端优化

代码分割:

// 使用React.lazy进行路由级别的代码分割
import { lazy, Suspense } from 'react';

const HomePage = lazy(() => import('./pages/Home'));
const ChatPage = lazy(() => import('./pages/Chat'));

function App() {
  return (
    <Suspense fallback={<div>加载中...</div>}>
      <Routes>
        <Route path="/" element={<HomePage />} />
        <Route path="/chat" element={<ChatPage />} />
      </Routes>
    </Suspense>
  );
}

组件级优化:

import { memo, useCallback, useMemo } from 'react';

// 使用memo避免不必要的重渲染
const AnimationComponent = memo(({ state }: { state: string }) => {
  return <div>{/* 动画内容 */}</div>;
});

// 使用useCallback缓存函数
const handleRecordStart = useCallback(() => {
  recorder.start();
}, []);

9.2 后端优化

连接池配置:

# 根据服务器资源调整连接池大小
CPU_COUNT = os.cpu_count() or 4
POOL_SIZE = CPU_COUNT * 2  # 经验值:CPU核心数的2倍

connection_pool = DoubaoConnectionPool(pool_size=POOL_SIZE)

异步优化:

# 使用asyncio.create_task而不是await,提高并发
task1 = asyncio.create_task(send_to_doubao(data))
task2 = asyncio.create_task(log_metrics(data))
# 不等待task完成,继续处理其他逻辑

10. 总结

10.1 核心组件清单

层级 组件 推荐方案 优先级
前端录音 音频采集 Recorder (xiangyuecn) ⭐⭐⭐⭐⭐
前端播放 音频播放 MediaSource API / Howler.js ⭐⭐⭐⭐⭐
前端框架 UI框架 React 18+ ⭐⭐⭐⭐⭐
前端状态 状态管理 Zustand ⭐⭐⭐⭐
前端动画 动画播放 Lottie ⭐⭐⭐⭐
前端构建 构建工具 Vite ⭐⭐⭐⭐⭐
后端框架 Web服务 FastAPI ⭐⭐⭐⭐⭐
后端异步 并发处理 asyncio ⭐⭐⭐⭐⭐
通信协议 WebSocket 原生WebSocket ⭐⭐⭐⭐⭐
部署 服务器 Nginx + Uvicorn ⭐⭐⭐⭐⭐

10.2 快速开始

# 1. 前端项目(在 frontend/ 目录)
cd /Users/wuzilong/work/00code/Tolan/frontend
npm install recorder-core howler zustand lottie-web
npm install -D tailwindcss postcss autoprefixer
npm run dev

# 2. 后端项目(在 backend/ 目录,使用本机Python)
cd /Users/wuzilong/work/00code/Tolan/backend

# 安装依赖(无需虚拟环境)
pip install fastapi uvicorn[standard] websockets python-dotenv loguru

# 启动开发服务器
python -m uvicorn main:app --reload

# 生产环境(使用SSL)
python -m uvicorn main:app --host 0.0.0.0 --port 8443 \
  --ssl-keyfile=../ssl/key.pem --ssl-certfile=../ssl/cert.pem

10.3 关键注意事项

  1. ✅ 使用Recorder的PCM引擎,确保输出16kHz、16bit、单声道的PCM数据
  2. ✅ 实时传输:在onProcess回调中立即发送数据,不要累积
  3. ✅ iOS兼容:必须在用户交互中初始化Recorder
  4. ✅ 连接池预热:后端启动时立即初始化连接池
  5. ✅ HTTPS必需:现代浏览器要求HTTPS才能访问麦克风

11. 环境配置总结

11.1 前端环境

# 进入前端目录
cd /Users/wuzilong/work/00code/Tolan/frontend

# 安装依赖
npm install

# 开发环境
npm run dev

# 生产构建
npm run build

11.2 后端环境(使用本机Python)

# 进入后端目录
cd /Users/wuzilong/work/00code/Tolan/backend

# 安装依赖(无需虚拟环境)
pip install -r requirements.txt

# 开发环境
python -m uvicorn main:app --reload --host 0.0.0.0 --port 8000

# 生产环境(使用SSL)
python -m uvicorn main:app --host 0.0.0.0 --port 8443 \
  --ssl-keyfile=../ssl/key.pem \
  --ssl-certfile=../ssl/cert.pem

11.3 访问地址


文档版本: v1.1
创建日期: 2025-10-08
最后更新: 2025-10-08
更新内容: 添加项目结构说明,更新为本机Python环境配置