Metadata-Version: 2.4
Name: ClassLiveSubtitle
Version: 1.0.6
Summary: Real-time speech translation CLI using Volcengine AST 2.0
Author-email: ChHsiching <hsichingchang@gmail.com>
License: MIT
Keywords: speech-translation,live-subtitle,volcengine,ast
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: End Users/Desktop
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: websockets>=13.0
Requires-Dist: protobuf>=5.0
Requires-Dist: sounddevice>=0.5.0
Requires-Dist: pyaudio>=0.2.14
Requires-Dist: python-dotenv>=1.0
Provides-Extra: linux
Requires-Dist: pulsectl>=24.0; extra == "linux"

# ClassLiveSubtitle — 课堂实时翻译字幕

> 基于火山引擎同声传译 2.0 (AST) 的实时语音翻译工具，带系统托盘 GUI 和浮动字幕。

对外教课堂上的英语进行实时翻译，中文悬浮字幕覆盖在屏幕下方。也支持 CLI 模式。

**功能：**
- 系统托盘图标 — 应用图标 + 状态指示圆点，一键开始/停止翻译
- 设置面板 — QWebEngine 驱动的现代 UI（Notion 风格），无边框窗口，深色/浅色主题
- 悬浮字幕 — 实时显示原文和翻译，支持拖拽移动，延迟创建避免黑屏
- 音量指示条 — 测试麦克风时实时显示音量
- 设备管理 — 设备热插拔自动刷新列表，断开自动切换系统默认
- 错误反馈 — 连接失败或异常时显示提示信息
- 断线自动重连 — 网络波动后自动恢复
- Linux 非独占录音 — PipeWire 逐流路由，不独占麦克风设备
- 设置持久化 — 麦克风、语言、字幕位置、字体大小自动保存
- API Key 引导 — 首次启动自动弹出配置向导，加密存储
- 快速退出 — 托盘图标立即消失，无残留
- 打包为 `ClassLiveSubtitle.exe` — 无需安装 Python，双击即用

---

## 快速开始

### 方式一：直接运行 exe（Windows）

1. 下载 `ClassLiveSubtitle.exe`
2. 双击运行
3. 首次启动会弹出 API Key 配置向导，按提示获取并粘贴 Key
4. 系统托盘出现应用图标
5. 右键托盘图标 → Settings... → 选择麦克风和语言
6. 右键托盘图标 → Start Translation 开始翻译

### 方式二：从源码运行

#### 前置要求

- **Python 3.12+**（推荐 3.12 或 3.13）
- **Git**

#### 方法 A：使用 uv（推荐）

```bash
# 安装 uv（只需一次）
# Windows:
winget install astral-sh.uv
# Linux/macOS:
curl -LsSf https://astral.sh/uv/install.sh | sh

# 克隆项目
git clone git@github.com:ChHsiching/ClassLiveSubtitle.git
cd ClassLiveSubtitle

# 创建虚拟环境并安装依赖
uv venv
uv pip install -r requirements.txt

# 激活虚拟环境
# Windows PowerShell:
.venv\Scripts\Activate.ps1
# Linux/macOS:
source .venv/bin/activate

# 启动 GUI
python -m gui
```

#### 方法 B：使用 pip

```bash
# 克隆项目
git clone git@github.com:ChHsiching/ClassLiveSubtitle.git
cd ClassLiveSubtitle

# 创建虚拟环境
python -m venv .venv

# 激活虚拟环境
# Windows PowerShell:
.venv\Scripts\Activate.ps1
# Linux/macOS:
source .venv/bin/activate

# 安装依赖
pip install -r requirements.txt

# 启动 GUI
python -m gui
```

> **注意：** 如果安装 pyaudio 报错：
> - **Ubuntu/Debian**: `sudo apt install portaudio19-dev` 然后重试
> - **macOS**: `brew install portaudio` 然后重试
> - **Windows**: 通常直接成功

---

## GUI 使用说明

### 设置面板

无边框 QWebEngine 窗口，支持：
- 麦克风设备选择与测试（绿色指示灯）
- 源语言切换（英文、德语、法语、日语等）
- 字幕样式预设（深色、浅色、透明）
- 显示模式（仅翻译、原文+翻译、仅原文）
- 字体大小滑块
- 深色/浅色主题切换

### 系统托盘菜单

右键托盘图标可以看到：

| 菜单项 | 功能 |
|--------|------|
| Start/Stop Translation | 开始或停止翻译 |
| Settings... | 打开设置面板 |
| Move Overlay | 开启/关闭字幕拖拽模式 |
| Show/Hide Subtitle | 显示或隐藏悬浮字幕 |
| Exit | 退出程序 |

### 托盘图标状态指示

图标右下角的圆点颜色表示当前状态：

| 圆点颜色 | 状态 |
|------|------|
| 蓝色 | 已连接，正在翻译 |
| 黄色 | 正在重连 |
| 灰色 | 未连接 |

### 悬浮字幕

- 默认显示在屏幕下方
- 开启 Move Overlay 后拖拽字幕窗口
- 支持"仅翻译"、"原文+翻译"、"仅原文"三种显示模式
- 字体大小可在设置面板调整

### 支持的语言

| 代码 | 语言 |
|------|------|
| `zh` | 中文 |
| `en` | 英文 |
| `ja` | 日语 |
| `id` | 印尼语 |
| `es` | 西班牙语 |
| `pt` | 葡萄牙语 |
| `de` | 德语 |
| `fr` | 法语 |
| `zhen` | 中英混合 |

---

## 打包为 exe

在 **Windows** 机器上运行（PyInstaller 不支持交叉编译）：

```bash
# 1. 确保已激活虚拟环境
.venv\Scripts\Activate.ps1

# 2. 安装依赖和 PyInstaller（选择你之前用的工具）
# uv 用户:
uv pip install -r requirements.txt pyinstaller
# pip 用户:
pip install -r requirements.txt pyinstaller

# 3. 打包
python packaging/build.py

# 输出
# dist/ClassLiveSubtitle.exe（约 200MB）
```

也可以清理后重新打包：

```bash
python packaging/build.py --clean
```

> **注意：** 打包时需要确保 `gui/web/` 目录存在（包含 HTML/CSS/JS 前端资源）。

---

## 高级：CLI 模式

除了 GUI，项目也提供命令行模式，适合脚本化使用或调试。

### 配置 API Key（CLI 专用）

GUI 模式首次启动时会自动弹出配置向导，无需手动操作。CLI 模式需要手动配置 `.env` 文件。

#### 第一步：获取 API Key

1. 注册 [火山引擎](https://www.volcengine.com) 账号并完成实名认证
2. 打开新版控制台：https://console.volcengine.com/speech/new
3. 左侧点击「语音同传大模型」→ 开通服务
4. 概览页 → API 接入 → 创建 API Key → 复制保存

#### 第二步：写入配置文件

```bash
cp .env.example .env
```

编辑 `.env` 文件：

```
AST_API_KEY=你的API_Key
AST_RESOURCE_ID=volc.service_type.10053
AST_WS_URL=wss://openspeech.bytedance.com/api/v4/ast/v2/translate
```

> **注意：** API Key 只在创建时显示一次，请立即保存！新版控制台只需 `AST_API_KEY` 一项。
> 旧版控制台用户需额外填写 `AST_ACCESS_KEY`，详见 [.env.example](.env.example)。

如需详细的 API Key 获取教程，参考以下官方文档：
- 快速入门：https://www.volcengine.com/docs/6561/2119699
- API Key 管理：https://www.volcengine.com/docs/6561/1816214
- 同声传译 2.0 API：https://www.volcengine.com/docs/6561/1756902

### CLI 运行

```bash
# 中文翻译成英文
python -m src --mode s2t --source zh --target en

# 英文翻译成中文
python -m src --mode s2t --source en --target zh

# 用音频文件测试
python -m src --mode s2t --source en --target zh --file test_audio.wav

# 查看可用麦克风
python -m src --list-devices

# 指定麦克风
python -m src --mode s2t --source en --target zh --device 2
```

### CLI 运行效果

```
🎙️  同声传译系统
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 模式: s2t (语音→文字) | zh → en
 麦克风: 16kHz/16bit/单声道 | 80ms/包
 按 Ctrl+C 停止
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

[原文] 今天我们来学习英语的基础语法
[译文] Today we are going to learn the basic grammar of English

[原文] 首先，我们来看一下名词的分类
[译文] First, let's look at the classification of nouns

^C
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
会话结束 | 时长: 45.2s | Token: 128
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```

### CLI 选项说明

| 选项 | 说明 | 默认值 |
|------|------|--------|
| `--mode` | `s2t`（仅文字）或 `s2s`（含语音） | `s2t` |
| `--source` | 源语言 | `zh` |
| `--target` | 目标语言 | `en` |
| `--file` | 音频文件路径 | 无 |
| `--device` | 麦克风设备编号 | 自动选择 |
| `--api-key` | 直接传 API Key | 从 .env 读取 |
| `--list-devices` | 列出所有麦克风设备 | — |
| `--debug` | 显示详细调试日志 | 关闭 |

---

## 常见问题

### GUI 相关

**Q: 托盘图标不显示？**
A: Windows 10/11 默认会隐藏新托盘图标。点击任务栏右下角的 `^` 箭头，找到应用图标，拖拽到任务栏即可。

**Q: 悬浮字幕位置不对？**
A: 右键托盘图标 → Move Overlay 开启拖拽模式，拖拽字幕到目标位置。位置会自动保存。

**Q: 翻译没有声音/不工作？**
A: 右键托盘图标 → Settings... → 确认选择了正确的麦克风设备。如果列表为空，检查系统麦克风权限。

**Q: 提示 "连接翻译服务失败，请检查网络"？**
A: 程序会自动重连（最多 3 次，间隔 2s/4s/8s）。如果持续失败，检查网络连接。

### CLI 相关

**Q: 提示 "AST_API_KEY is required"？**
A: 需要配置 `.env` 文件，参见 [配置 API Key](#配置-api-keycli-专用)。

**Q: 提示 "连接失败: HTTP 401"？**
A: 认证失败。确认已在火山引擎控制台开通同声传译服务，且 API Key 正确。新版控制台只需 `AST_API_KEY`。

**Q: 麦克风没有声音？**
A: 运行 `python -m src --list-devices` 查看设备，用 `--device` 指定编号。确保系统已授权麦克风权限。

**Q: 安装 pyaudio 报错？**
A:
- **Ubuntu/Debian**: `sudo apt install portaudio19-dev`
- **macOS**: `brew install portaudio`
- **Windows**: 安装 [Visual Studio Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/)

**Q: 翻译延迟较大？**
A: 正常现象。语速适中、句间停顿可降低延迟。s2t 模式比 s2s 延迟更小。

---

## 项目结构

```
ClassLiveSubtitle/
├── gui/                        # GUI 应用
│   ├── __main__.py             # 入口：python -m gui
│   ├── app.py                  # 应用初始化，托盘/Worker/字幕生命周期管理
│   ├── main_window.py          # QWebEngineView 容器 + BackendAPI 桥接
│   ├── web_api.py              # Python↔JS 双向桥接（QWebChannel）
│   ├── secrets.py              # API Key 加密存储
│   ├── web/                    # HTML/CSS/JS 前端
│   │   ├── index.html          # 设置面板页面
│   │   ├── style.css           # 主题系统（Notion 设计语言）
│   │   ├── app.js              # 前端逻辑与信号处理
│   │   ├── qwebchannel.js      # Qt WebChannel 客户端
│   │   ├── fonts/              # Inter 字体（400/500/600）
│   │   └── assets/             # 图标（PNG + ICO）
│   ├── overlay.py              # 悬浮字幕窗口（原生 Qt）
│   ├── bridge.py               # Worker → UI 信号桥
│   ├── worker.py               # 异步翻译 Worker 线程
│   ├── persistence.py          # 设置持久化（JSON）
│   ├── status.py               # 会话状态常量
│   ├── style.py                # 字体加载
│   └── tray.py                 # 系统托盘图标和菜单
├── src/                        # 核心翻译引擎
│   ├── cli.py                  # CLI 入口：python -m src
│   ├── client.py               # WebSocket 客户端
│   ├── config.py               # 配置管理
│   ├── microphone.py           # 麦克风采集（自动选择后端）
│   ├── player.py               # 音频播放
│   ├── protocol.py             # Protobuf 协议封装
│   ├── subtitle.py             # 字幕渲染
│   ├── audio/                  # 平台感知设备管理
│   │   ├── device_manager.py   # DeviceManager 协议 + Linux/Windows 实现
│   │   └── hotplug.py          # 设备热插拔检测
│   └── backends/               # 音频后端
│       ├── sounddevice_backend.py
│       └── pyaudio_backend.py
├── packaging/                  # 打包配置
│   ├── ClassLiveSubtitle.spec  # PyInstaller 规格文件
│   ├── build.py                # 构建脚本
│   └── package.sh              # 打包 zip 脚本
├── python_protogen/            # Protobuf 生成代码
├── tests/                      # 测试（298 个）
├── requirements.txt            # Python 依赖
├── .env.example                # API Key 配置模板（CLI 用）
└── README.md                   # 本文件
```

---

## 技术说明

本项目基于火山引擎 [同声传译 2.0 API](https://www.volcengine.com/docs/6561/1756902) 实现，使用 WebSocket + Protobuf 协议与 AST 服务通信。

音频格式：16kHz 采样率、16bit 采样精度、单声道 PCM，80ms 分包。
GUI 框架：PySide6 (Qt)，设置面板使用 QWebEngine + HTML/CSS/JS，悬浮字幕使用原生 Qt。打包：PyInstaller onefile。
