AI 同声传译助手是一个面向英文视频、直播、会议和口语场景的实时字幕翻译系统。它通过 Chrome 插件侧边栏采集麦克风或当前标签页音频,将音频实时送到后端完成流式 ASR、机器翻译、AI 校正,并在侧边栏和视频浮层中显示中文字幕。
项目重点解决两个问题:一是让用户观看英文内容时尽快看到可理解的中文字幕;二是通过 ASR final、TMT baseline、DeepSeek refine/revise 等多阶段策略,在低延迟和翻译准确性之间取得平衡。
- Chrome Side Panel 作为统一主界面
- 支持麦克风输入和当前标签页音频
- 前端统一输出 16kHz mono Int16 PCM
- WebSocket
/ws/translate实时传输音频 - 腾讯云 Streaming ASR 获取英文 interim/final 文本
- 本地 draft 字幕降低首屏等待感
- 腾讯云 TMT 生成低延迟 baseline 翻译
- DeepSeek 对 final 字幕做 refine,并可根据后续上下文 revised
- 字幕支持
draft、partial、final、revised - 视频 overlay 可选显示当前 active subtitle
- 侧边栏支持历史字幕、运行日志和清除所有字幕
git clone https://github.com/iridescentiii/Trans_app.git
cd Trans_app建议使用 Python 3.10+。
python -m venv .venvWindows PowerShell:
.\.venv\Scripts\Activate.ps1macOS / Linux:
source .venv/bin/activate安装依赖:
pip install -r requirements.txt复制模板:
copy backend\.env.example backend\.envmacOS / Linux:
cp backend/.env.example backend/.env编辑 backend/.env,至少需要配置腾讯云 ASR/TMT 和 DeepSeek:
ASR_PROVIDER=cloud_streaming
CLOUD_ASR_VENDOR=tencent
CLOUD_ASR_APP_ID=
CLOUD_ASR_API_KEY=
CLOUD_ASR_SECRET=
CLOUD_ASR_SAMPLE_RATE=16000
TENCENT_ASR_ENGINE_MODEL_TYPE=16k_en
BASE_TRANSLATE_ENABLED=true
BASE_TRANSLATE_PROVIDER=tencent_tmt
TENCENT_TMT_REGION=ap-shanghai
TENCENT_TMT_SOURCE=en
TENCENT_TMT_TARGET=zh
TENCENT_TMT_PROJECT_ID=0
AI_REFINE_ENABLED=true
AI_REFINE_PROVIDER=deepseek
AI_REFINE_ON_FINAL=true
AI_REFINE_ON_REVISED=true
DEEPSEEK_API_KEY=
DEEPSEEK_BASE_URL=https://api.deepseek.com/v1
DEEPSEEK_MODEL=deepseek-chat注意:
backend/.env只放本地真实密钥,不要提交到 Git。- 腾讯云 ASR 和 TMT 需要在腾讯云控制台开通对应服务。
- 如果只想先跑通 TMT baseline,可以临时设置
AI_REFINE_ENABLED=false。 - 如果 revised 后台校正频繁报错,可以临时设置
REVISION_ENABLED=false。
进入后端目录:
cd backend启动 FastAPI:
python -m uvicorn main:app --reload --host 0.0.0.0 --port 8000看到类似输出即表示后端启动成功:
Uvicorn running on http://0.0.0.0:8000
浏览器访问健康检查:
http://127.0.0.1:8000/docs
- 打开 Chrome。
- 访问
chrome://extensions。 - 打开右上角“开发者模式”。
- 点击“加载已解压的扩展程序”。
- 选择项目中的
extension/目录。 - 点击浏览器工具栏中的插件图标,打开侧边栏。
- 在侧边栏选择“麦克风输入”。
- 点击“开始同传”。
- 浏览器弹出麦克风授权时选择“允许”。
- 对麦克风说英文。
- 侧边栏会显示实时中文字幕。
如果出现 Permission dismissed,表示麦克风授权弹窗被关闭了,需要重新点击“开始同传”并选择允许。
- 打开普通网页视频页面,例如 YouTube、网课、直播页面。
- 点击插件图标打开侧边栏。
- 选择“当前标签页音频”。
- 点击“绑定当前标签页”。
- 点击“开始同传”。
- 如开启“视频浮层字幕”,当前页面会显示 overlay 字幕。
注意:
- Chrome 新标签页、
chrome://页面、扩展管理页不能被捕获。 - 如果只使用麦克风输入,不需要绑定网页。
用户说:Today we are talking about large language models.
侧边栏显示:今天我们正在讨论大语言模型。
YouTube / 网课 / 直播标签页音频
→ Chrome tabCapture
→ PCM 16kHz mono
→ WebSocket /ws/translate
→ 腾讯云 Streaming ASR
→ TMT partial
→ DeepSeek final/revised
→ 视频 overlay 中文字幕
| 状态 | 含义 |
|---|---|
draft |
本地词典生成的快速草稿字幕,用于尽快显示中文 |
partial |
腾讯云 TMT baseline 生成的临时字幕,可被后续 partial/final 覆盖 |
final |
ASR final 后,TMT baseline + DeepSeek refine 生成的稳定字幕 |
revised |
DeepSeek 根据后续上下文修正最近 final 字幕 |
| 提示 | 含义 | 处理方式 |
|---|---|---|
Permission dismissed |
麦克风授权弹窗被关闭 | 重新点击开始并允许麦克风 |
Base machine translation failed |
腾讯云 TMT baseline 翻译失败 | 检查 TMT 是否开通、密钥和地区配置 |
DeepSeek refine failed, fallback to baseline translation |
DeepSeek final 校正失败,已退回 TMT 结果 | 检查 DeepSeek key、模型、网络、余额 |
DeepSeek revised check failed |
后台 revised 检查失败 | 可临时设置 REVISION_ENABLED=false |
ASR provider failed to start |
腾讯云 ASR 未启动成功 | 检查 ASR app id、secret id、secret key 和网络 |
Trans_app/
├── backend/
│ ├── main.py # FastAPI 应用入口
│ ├── config.py # 环境变量与全局配置
│ ├── .env.example # 后端配置模板
│ ├── api/
│ │ └── websocket.py # /ws/translate 实时同传 WebSocket
│ ├── models/
│ │ └── schemas.py # Pydantic 消息结构
│ └── services/
│ ├── asr/ # ASR Provider 抽象与腾讯云 Streaming ASR
│ ├── translation/ # DeepSeek、腾讯 TMT、翻译 Provider
│ ├── draft_translation_service.py
│ ├── subtitle_revision_service.py
│ ├── translation_stream_service.py
│ └── session_service.py
├── extension/
│ ├── manifest.json # Chrome Extension MV3 配置
│ ├── sidepanel.html # 插件侧边栏主界面
│ ├── sidepanel.js # 侧边栏交互、麦克风采集、字幕状态
│ ├── sidepanel.css # 侧边栏样式
│ ├── background.js # WebSocket、tabCapture、消息转发
│ ├── offscreen.html # tab audio capture offscreen document
│ ├── offscreen.js # 标签页音频采集与 PCM 转发
│ ├── pcmWorkletProcessor.js # AudioWorklet PCM 重采样与分帧
│ └── contentScript.js # 视频页面 overlay 字幕
├── frontend/
│ └── src/ # Vue 调试页面,主要用于开发测试
├── requirements.txt # Python 后端依赖
└── README.md
系统采用“Chrome 插件侧边栏 + FastAPI 后端 + 云端 ASR/翻译服务”的结构。
音频来源
├── 麦克风输入
└── 当前标签页音频
↓
Chrome Extension Side Panel / Offscreen
↓
16kHz mono Int16 PCM
↓
WebSocket /ws/translate
↓
Tencent Streaming ASR
↓
ASR interim / final
↓
Draft / TMT partial / DeepSeek final / DeepSeek revised
↓
subtitle_update / subtitle_delta
↓
Side Panel + Video Overlay
插件只负责采集音频、显示状态和渲染字幕;后端统一负责 ASR、翻译、分段、revision 和消息协议。
Chrome 插件使用 Manifest V3。Side Panel 是正式主界面,Popup 仅保留为兼容入口。
侧边栏包含:
- 音频来源选择:麦克风输入 / 当前标签页音频
- 开始、暂停、停止
- 清除所有字幕
- 实时字幕
- WebSocket / ASR / PCM / 字幕状态
- 显示设置
- 历史字幕
- 运行日志
麦克风输入在 sidepanel.js 中通过可见页面调用:
navigator.mediaDevices.getUserMedia({ audio: true })这样可以让 Chrome 正常弹出麦克风授权。授权成功后,侧边栏通过 AudioWorklet 将音频转为 PCM 并发送给 background。
当前标签页音频使用:
chrome.tabCapture.getMediaStreamId
→ offscreen document
→ getUserMedia(chromeMediaSource="tab")
tab audio capture 不能用于 chrome://、新标签页、扩展页面等特殊页面。
前端统一输出:
format: pcm_s16le
sample_rate: 16000
channels: 1
frame_duration_ms: 100
启动后先发送 audio_config:
{
"type": "audio_config",
"event": "audio_config",
"source": "microphone",
"format": "pcm_s16le",
"sample_rate": 16000,
"channels": 1,
"frame_duration_ms": 100,
"language": "en",
"engine_model_type": "16k_en"
}随后持续发送二进制 PCM frame。
后端收到 audio_config 后启动 ASR Provider;收到 PCM frame 后转发给云端 ASR。
ASR 采用 Provider 抽象,当前主链路使用腾讯云 Streaming ASR:
ASR_PROVIDER=cloud_streaming
CLOUD_ASR_VENDOR=tencent
腾讯云 ASR 返回的 slice_type 会被标准化为内部事件:
腾讯 slice_type |
内部事件 |
|---|---|
0 / 1 |
ASREvent(is_final=false) |
2 |
ASREvent(is_final=true) |
后端会打印 raw response 和 normalized event,便于排查是否真的收到 interim。
项目没有只依赖一个 LLM 直接翻译,而是拆成三层:
ASR interim → local draft → TMT partial
ASR final → TMT baseline → DeepSeek refine → final
后续上下文 → DeepSeek revise → revised
draft 是本地词典/短语规则字幕,用于降低“刚开始说话时没有字幕”的等待感。
特点:
- 不走网络,请求延迟极低;
- 只输出安全中文;
- 不会把英文原文伪装成中文;
- 置信度不足时跳过。
partial 使用腾讯云 TMT baseline 翻译。
特点:
- 不调用 DeepSeek;
- 低延迟优先;
- 可被后续 partial 覆盖;
- 可被 final/revised 覆盖;
- TMT 失败时不会回显英文。
final 在 ASR final 到来后执行:
完整英文 final text
→ 腾讯云 TMT baseline
→ DeepSeek refine
→ subtitle_update(status="final")
DeepSeek refine 失败时,系统会 fallback 到 TMT baseline,并标记 translation_source="tencent_tmt_fallback"。
final 完成后,后台异步检查最近 1 到 2 条字幕是否需要根据后续上下文修正。
特点:
- 不阻塞实时链路;
- 每条字幕最多 revised 一次;
- 只在明显错误时修正;
- revised 可以覆盖 final;
- partial 不能覆盖 final/revised。
为了避免“上一句 final 翻译中,下一句 ASR interim 被跳过”,后端使用 segment-level 状态,而不是 session 级 final task 阻塞。
核心规则:
- 每个 segment 独立维护 partial/final/revised;
- ASR final 到来后立即释放 active segment;
- final/refine 在后台运行;
- 下一句 interim 可以立刻创建新 segment;
- 旧 revision 的消息不能覆盖新字幕;
- partial 不能覆盖 final/revised。
完整字幕更新:
{
"type": "subtitle_update",
"event": "subtitle_update",
"segment_id": 1,
"revision": 3,
"status": "partial",
"source_text": "You can choose",
"translation": "你可以选择",
"target_text": "你可以选择",
"is_final": false
}字幕状态优先级:
draft < partial < final < revised
前端根据 segment_id + revision + status 判断是否覆盖:
- 低 revision 丢弃;
- partial 不能覆盖 final/revised;
- final 可以覆盖 partial;
- revised 可以覆盖 final;
- overlay 只显示当前 active subtitle。
传统机器翻译和 LLM 都不是严格“零延迟”。为了让用户感知更实时,系统采用:
- ASR interim 一出现,尽快输出 draft;
- TMT baseline 返回后覆盖 partial;
- 按英文源文本 15 词窗口滚动字幕;
- 窗口切换后重新逐字输出;
- final/revised 到来后立即覆盖旧字幕;
- 前端避免旧动画队列阻塞新字幕。
相关配置:
FIRST_PARTIAL_MIN_WORDS=1
FIRST_PARTIAL_MIN_CHARS=1
FIRST_PARTIAL_MAX_WAIT_MS=120
PARTIAL_TRANSLATE_INTERVAL_MS=350
PARTIAL_TRANSLATE_MIN_WORDS=2
PARTIAL_TRANSLATE_MIN_NEW_WORDS=1
PARTIAL_SOURCE_WINDOW_WORDS=15
DRAFT_SUBTITLE_ENABLED=true
DRAFT_UPDATE_INTERVAL_MS=120系统遵守以下原则:
- 不允许把英文原文伪装成中文字幕;
- TMT partial 失败时保持当前字幕或发 error;
- DeepSeek final refine 失败时可 fallback 到 TMT baseline;
- revised 失败不影响主链路;
- WebSocket 不因翻译失败主动断开;
- 日志不打印 API Key、SecretKey、Authorization header 或完整签名。
frontend/ 中的 Vue 页面保留为开发调试入口,主要用于测试 WebSocket、麦克风链路和字幕渲染。正式产品入口是 Chrome 插件 Side Panel。
常用检查:
node --check extension/sidepanel.js
node --check extension/background.js
node --check extension/contentScript.js后端启动:
cd backend
python -m uvicorn main:app --reload --host 0.0.0.0 --port 8000查看本地端口:
Test-NetConnection 127.0.0.1 -Port 8000- 不要提交
backend/.env。 .env.example只保留模板。- 不要在日志中输出腾讯云 SecretKey、DeepSeek API Key 或 Authorization header。
- Chrome 插件不要添加
audioCapture权限;它只允许 packaged apps,不适用于普通扩展。
demo演示地址:【ai实时翻译助手】 https://www.bilibili.com/video/BV1ZrE86hE6X/?share_source=copy_web&vd_source=370fd96634fbfc4c949a8b8ca468923f