# ZSimulCast **Repository Path**: blueTomCat/zsimulcast ## Basic Information - **Project Name**: ZSimulCast - **Description**: AI 同声传译助手 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-05 - **Last Updated**: 2026-06-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ZSimulCast — AI 同声传译助手 > 通过 AI 能力,将单向音频流实时、流畅地翻译成中文,以字幕或语音形式呈现。 [![Spring Boot](https://img.shields.io/badge/Spring%20Boot-3.3.5-green)](https://spring.io/projects/spring-boot) [![Vue](https://img.shields.io/badge/Vue-3.5-brightgreen)](https://vuejs.org/) [![JDK](https://img.shields.io/badge/JDK-21-orange)](https://openjdk.org/projects/jdk/21/) [![MySQL](https://img.shields.io/badge/MySQL-8.0-blue)](https://www.mysql.com/) [![Redis](https://img.shields.io/badge/Redis-7.0-red)](https://redis.io/) --- ## 功能特性 | 功能 | 说明 | |------|------| | 🎤 多种音频输入 | 系统音频捕获、麦克风输入、本地文件解码 | | 🌐 实时字幕翻译 | 音频流实时识别为文字并翻译,以字幕形式展示 | | 🔧 上下文修正 | LLM 大模型自动发现并纠正之前识别或翻译的错误 | | 🔊 TTS 语音播报 | 基于 Web Speech API 的浏览器端语音合成 | | 📋 翻译历史 | 持久化存储翻译记录,支持分页查询和一键删除 | | 📝 字幕导出 | 支持导出为 SRT / WebVTT 标准字幕文件格式 | | 📖 术语库管理 | 用户自定义专业术语,提升翻译准确度 | | 🎨 主题自定义 | 深色 / 浅色模式切换,字幕样式自由调节 | | 🔑 自带 API Key | 用户自主选择 AI 服务商,API Key 加密存储不落盘 | | 📱 响应式适配 | 同时适配桌面、平板、手机三种设备 | ## 技术栈 | 层级 | 技术选型 | 版本 | |------|----------|------| | 后端框架 | Spring Boot | 3.3.5 | | ORM | MyBatis-Plus | 3.5.16 | | 实时通信 | Jakarta WebSocket | — | | 异步消息 | Redis Stream | — | | 前端框架 | Vue 3 + TypeScript | 3.5 | | UI 组件库 | Element Plus | 2.12 | | 构建工具 | Vite | 8.x | | 数据库 | MySQL | 8.0 | | 缓存 / 消息队列 | Redis | 7.0 | | 编程语言 | Java 21 / TypeScript 6.0 | — | ## 系统架构 ``` 浏览器 (Vue 3) Spring Boot 后端 基础设施 ┌──────────────┐ WebSocket ┌──────────────────┐ ┌─────────────┐ │ 音频采集模块 │─────PCM──────▶│ ASR 适配器 │ │ │ │ 字幕实时展示 │◄────JSON─────│ Azure·Google· │ │ MySQL 8.0 │ │ 设置面板 │ │ 阿里云·火山引擎 │ │ 用户表 │ │ 历史记录 │ └────────┬──────────┘ │ 会话表 │ └──────────────┘ │ │ 配置表 │ ┌─────────▼──────────┐ │ 历史记录表 │ │ 翻译适配器 │ │ 术语库表 │ │ OpenAI·DeepL· │ └──────┬──────┘ │ Google·Azure·百度 │ │ └────────┬──────────┘ ┌──────▼──────┐ │ │ Redis 7.0 │ ┌────────▼──────────┐ │ 缓存 │ │ Redis Stream 队列 │ │ Stream │ │ 历史保存·邮件发送 │ │ 消息队列 │ │ 登录事件·LLM 修正 │ └─────────────┘ └───────────────────┘ ``` **数据流说明**: 1. 前端采集 PCM 音频,通过 WebSocket 二进制帧发送到后端 2. 后端 ASR 适配器调用语音识别服务,获取识别文本 3. 翻译适配器将识别结果翻译为目标语言 4. 翻译结果即时通过 WebSocket JSON 推送到前端展示 5. 非核心操作(历史保存、邮件发送、登录日志、LLM 修正)发布到 **Redis Stream**,由后台消费者异步处理 --- ## 快速开始 ### 环境要求 | 依赖 | 最低版本 | 推荐版本 | |------|----------|----------| | JDK | 21 | 21 LTS | | Maven | 3.8 | 3.9+ | | Node.js | 18 | 20 LTS | | MySQL | 8.0 | 8.0+ | | Redis | 6.0 | 7.0+ | ### 第一步:克隆项目 ```bash git clone https://github.com/your-org/ZSimulCast.git cd ZSimulCast git checkout dev ``` ### 第二步:启动 MySQL 和 Redis ```bash # 推荐使用 Docker 一键启动 docker compose -f docker/docker-compose.yml up -d mysql redis # 或者手动安装并启动 MySQL 8.0 + Redis 7.0 ``` > 如果使用 Docker,MySQL 的 `zsimulcast` 数据库会由 `docker/init.sql` 自动创建。 ### 第三步:配置应用 ```bash cd backend cp src/main/resources/application-dev.yml.example src/main/resources/application-dev.yml ``` 编辑 `application-dev.yml`,修改数据库和 Redis 连接信息: ```yaml spring: datasource: # 注意 URL 末尾的 createDatabaseIfNotExist=true 会自动建库 url: jdbc:mysql://你的IP:3306/zsimulcast?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false&createDatabaseIfNotExist=true username: 你的数据库用户名 password: 你的数据库密码 data: redis: host: 你的Redis地址 port: 6379 password: 你的Redis密码(如果没有可以删除这行) ``` > **首次启动**:Spring Boot 会自动建库(如果不存在)、建表(5 张)、插入测试数据,**无需手动执行任何 SQL**。 ### 第四步:启动后端 ```bash cd backend mvn spring-boot:run ``` 后端运行在 `http://localhost:8080` ### 第五步:启动前端 ```bash cd frontend npm install npm run dev ``` 前端运行在 `http://localhost:5173` ### 第六步:开始使用 1. 打开浏览器访问 `http://localhost:5173` 2. 进入**设置页面**,配置你的 AI 服务商 API Key(支持 Azure / OpenAI / DeepL / 百度等) 3. 选择音频源:系统音频(录播/会议)/ 麦克风 / 本地文件 4. 点击**开始翻译**,实时字幕即刻呈现 --- ## 生产部署 ### 需要部署的服务 整个项目**只需要两个基础服务**: | 服务 | 用途 | 端口 | |------|------|:--:| | **MySQL 8.0** | 用户、会话、配置、历史记录、术语库等结构化数据 | 3306 | | **Redis 7.0** | 缓存(验证码、签名防重放)+ Stream 消息队列(异步历史/邮件/修正) | 6379 | > 🔹 **不需要** RabbitMQ / Kafka — Redis Stream 替代了传统消息队列,处理历史保存、邮件发送、登录日志、LLM 修正等异步任务。 > > 🔹 **不需要** MinIO / OSS 文件存储 — 字幕文件由后端实时生成,直接通过 HTTP 响应下载。 > > 🔹 **不需要** 部署 AI 模型 — 用户自带 API Key,后端仅做代理转发,AI 能力由外部服务商提供。 ### 后端部署 ```bash cd backend mvn clean package -DskipTests java -jar target/zsimulcast-backend-0.1.0.jar --spring.profiles.active=prod ``` 生产环境配置文件 `application-prod.yml`: ```yaml server: port: 8080 spring: datasource: url: jdbc:mysql://生产数据库IP:3306/zsimulcast?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=true&createDatabaseIfNotExist=true username: ${DB_USERNAME} password: ${DB_PASSWORD} hikari: minimum-idle: 10 maximum-pool-size: 50 data: redis: host: ${REDIS_HOST} port: 6379 password: ${REDIS_PASSWORD} lettuce: pool: max-active: 16 sql: init: mode: always schema-locations: classpath:schema-mysql.sql zsimulcast: jwt: secret: ${JWT_SECRET} # 环境变量注入,至少 32 字节 encryption: master-key: ${ENC_MASTER_KEY} # 环境变量注入,Base64 编码的 AES-256 密钥 ``` > ⚠️ **安全提示**:`JWT_SECRET` 和 `ENC_MASTER_KEY` 必须通过环境变量注入,切勿硬编码在配置文件中。 ### 前端部署 ```bash cd frontend npm run build ``` 生成的 `dist/` 目录部署到 Nginx 或任何静态文件服务器。 ### Nginx 配置 ```nginx server { listen 80; server_name your-domain.com; # 前端静态文件 root /var/www/zsimulcast; index index.html; # Vue Router history 模式 location / { try_files $uri /index.html; } # WebSocket 代理(实时翻译通道) location /ws/ { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_read_timeout 86400s; proxy_send_timeout 86400s; } # REST API 代理 location /api/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } ``` ### 健康检查 ```bash curl http://localhost:8080/actuator/health # {"status":"UP","components":{"db":{"status":"UP"},"redis":{"status":"UP"}}} ``` --- ## 项目结构 ``` ZSimulCast/ ├── backend/ # Spring Boot 后端 │ ├── pom.xml │ └── src/main/java/com/zsimulcast/ │ ├── asr/ # ASR 语音识别适配器 │ │ ├── AzureAsrClient.java # Azure Speech-to-Text │ │ ├── GoogleAsrClient.java # Google Cloud Speech │ │ ├── AliyunAsrClient.java # 阿里云语音识别 │ │ └── VolcengineAsrClient.java # 火山引擎语音识别 │ ├── common/ # 公共组件 │ │ ├── RedisService.java # Redis 封装(含 Stream 操作) │ │ └── enums/ # 枚举(语言/服务商/错误码) │ ├── config/ # Spring 配置 │ │ ├── RedisConfig.java # RedisTemplate 序列化 │ │ ├── SecurityConfig.java # Spring Security │ │ └── CorsConfig.java # 跨域配置 │ ├── correction/ # 上下文修正引擎 │ │ └── LlmCorrectionEngine.java # LLM 上下文修正检查 │ ├── glossary/ # 术语库模块 │ ├── history/ # 翻译历史记录 │ │ └── service/ │ │ └── HistoryService.java # SRT/VTT 导出 │ ├── mail/ # 邮件验证码 │ ├── proxy/ # API 代理层 │ │ └── BaseApiClient.java # 统一重试/错误映射 │ ├── security/ # 安全模块 │ │ ├── EncryptionServiceImpl.java # AES-256-GCM 加密 │ │ ├── JwtServiceImpl.java # JWT 签发/验证 │ │ └── SignatureServiceImpl.java # 请求签名防重放 │ ├── session/ # 会话管理 │ ├── stream/ # 🆕 Redis Stream 异步消息 │ │ ├── StreamKeys.java # Stream Key 常量 │ │ ├── StreamProducer.java # 消息生产者(XADD) │ │ ├── StreamConsumer.java # 消费者抽象基类 │ │ ├── event/ # 事件定义 │ │ │ ├── HistorySaveEvent.java │ │ │ ├── EmailSendEvent.java │ │ │ ├── LoginEvent.java │ │ │ └── CorrectionEvent.java │ │ ├── consumer/ # 消费者实现 │ │ │ ├── HistorySaveConsumer.java │ │ │ ├── EmailSendConsumer.java │ │ │ ├── LoginEventConsumer.java │ │ │ └── CorrectionConsumer.java │ │ └── config/ │ │ └── StreamConfig.java # 消费者启动管理 │ ├── tenant/ # 多租户隔离 │ ├── translate/ # 翻译适配器 │ │ ├── OpenAiTranslateClient.java │ │ ├── DeepLTranslateClient.java │ │ ├── GoogleTranslateClient.java │ │ ├── AzureTranslateClient.java │ │ └── BaiduTranslateClient.java │ ├── user/ # 用户注册/登录 │ ├── userconfig/ # 用户 ASR/翻译/LLM 配置 │ └── websocket/ # WebSocket 实时翻译 │ ├── TranslateEndpoint.java # /ws/translate 端点 │ ├── audio/AudioBuffer.java # PCM 音频缓冲 │ ├── pipeline/ # 流水线处理 │ ├── protocol/ # 消息协议 │ └── session/ # 会话状态机 ├── frontend/ # Vue 3 前端 │ └── src/ │ ├── views/ # 页面组件 │ │ ├── HomeView.vue # 实时翻译主页 │ │ ├── LoginView.vue # 登录页 │ │ ├── RegisterView.vue # 注册页 │ │ ├── SettingsView.vue # 设置页(API Key/语言/主题) │ │ ├── HistoryView.vue # 历史记录页 │ │ └── GlossaryView.vue # 术语库页 │ ├── services/ # 服务层 │ │ ├── api.ts # HTTP API 客户端 │ │ ├── websocket.ts # WebSocket 管理器 │ │ └── AudioCapture.ts # 音频采集(系统/麦克风/文件) │ ├── stores/auth.ts # Pinia 认证状态 │ ├── router/index.ts # Vue Router + 路由守卫 │ └── styles/global.css # 全局样式 + 深色模式 ├── docs/ # 项目文档 │ ├── README.md # 详细规划文档(19 章) │ ├── dev-log.md # 后端开发日志 │ ├── frontend-dev-log.md # 前端开发日志 │ └── ai-assistant-rules.md # AI 助手指令 ├── docker/ │ ├── docker-compose.yml # MySQL + Redis │ └── init.sql # 仅建库 ├── CLAUDE.md # AI 开发规范 └── README.md # 本文件 ``` --- ## API 接口 ### REST API | 接口 | 方法 | 说明 | 认证 | |------|------|------|:--:| | `/api/auth/send-code` | POST | 发送邮箱验证码(异步 Redis Stream) | — | | `/api/auth/register` | POST | 用户注册 | — | | `/api/auth/login` | POST | 用户登录(登录日志异步更新) | — | | `/api/auth/refresh` | POST | 刷新 Token | — | | `/api/user/me` | GET | 获取当前用户信息 | JWT | | `/api/session/anonymous` | POST | 创建匿名会话 | — | | `/api/config` | GET | 获取用户配置 | JWT | | `/api/config` | PUT | 更新用户配置 | JWT | | `/api/config` | DELETE | 删除用户配置 | JWT | | `/api/history/session/{id}` | GET | 分页查询翻译历史 | JWT | | `/api/history/session/{id}` | DELETE | 删除会话历史 | JWT | | `/api/history/export/{id}` | GET | 导出 SRT / VTT 字幕文件 | JWT | | `/api/glossary` | GET/POST | 查询 / 添加术语 | JWT | | `/api/glossary/{id}` | DELETE | 删除术语 | JWT | ### WebSocket | 端点 | 说明 | 认证 | |------|------|:--:| | `/ws/translate` | 实时翻译,接收二进制音频帧 + JSON 信令,推送翻译/修正结果 | JWT(握手时验证) | ### 信令协议 | 消息类型 | 方向 | 说明 | |----------|------|------| | `start` | 客户端 → 服务端 | 开始翻译,携带源语言和目标语言 | | `stop` | 客户端 → 服务端 | 停止翻译 | | `ping` | 双向 | 心跳保活 | | `translation` | 服务端 → 客户端 | 翻译结果(seq + 原文 + 译文 + 时间戳) | | `correction` | 服务端 → 客户端 | 修正结果(seq + 修正后译文 + 原因) | | `error` | 服务端 → 客户端 | 错误信息 | --- ## 支持的 AI 服务商 | 功能 | 已对接服务商 | |------|-------------| | **ASR 语音识别** | Azure Speech / Google Cloud Speech / 阿里云 / 火山引擎 | | **翻译** | OpenAI / DeepL / Google Translate / Azure Translator / 百度翻译 | | **LLM 上下文修正** | OpenAI 兼容 API(通义千问 / DeepSeek / 本地模型等) | --- ## 数据库 启动时由 Spring Boot `sql.init` 自动建表,包含以下 5 张表: | 表名 | 说明 | 关键字段 | |------|------|----------| | `user` | 用户表 | email, password_hash(BCrypt), last_login_at | | `session` | 会话表 | session_id, user_id, expires_at | | `user_config` | 用户配置表 | ASR/翻译服务商、API Key(加密)、LLM 设置 | | `history_record` | 历史记录表 | original_text, translated_text, message_seq | | `glossary` | 术语库表 | source_term, target_term | 建表脚本:`backend/src/main/resources/schema-mysql.sql` 测试数据:`backend/src/test/resources/data-mysql.sql` --- ## 文档 | 文档 | 路径 | 说明 | |------|------|------| | 项目规划 | [docs/README.md](./docs/README.md) | 系统架构、模块划分、安全策略、性能目标(19 章) | | 后端开发日志 | [docs/dev-log.md](./docs/dev-log.md) | Phase 0-11 完整开发记录 | | 前端开发日志 | [docs/frontend-dev-log.md](./docs/frontend-dev-log.md) | Phase F0-F11 完整开发记录 | | AI 助手指令 | [CLAUDE.md](./CLAUDE.md) | 提交规范、技术偏好、禁止事项 | ## License MIT