Initial commit: lesson-highlights generator

This commit is contained in:
hmo
2026-05-03 03:07:22 +08:00
commit 9e62247a60
55 changed files with 6189 additions and 0 deletions
+477
View File
@@ -0,0 +1,477 @@
# Piano Highlight Generator App - 任务拆解
> 创建日期:2026-05-02
> 基于:design.md
---
## 任务总览
| # | 任务 | 依赖 | 优先级 | 工期 |
|---|------|------|--------|------|
| 1 | 项目骨架搭建 | - | P0 | 1h |
| 2 | ConfigPanel 配置面板 | 1 | P0 | 1h |
| 3 | StateManager 状态管理 | 1 | P0 | 0.5h |
| 4 | ProgressView 进度视图 | 1 | P0 | 1h |
| 5 | Worker 后台线程 | 1 | P0 | 1h |
| 6 | PipelineController 流水线控制 | 3, 5 | P0 | 1.5h |
| 7 | TitleEditor 标题编辑器 | 6 | P1 | 1.5h |
| 8 | 主窗口集成 | 2, 4, 7 | P0 | 1h |
| 9 | 核心模块适配 | 1 | P0 | 0.5h |
| 10 | 错误处理完善 | 8 | P2 | 1h |
| 11 | 打包配置 + 测试 | 10 | P2 | 1.5h |
| 12 | 文档和 README | 11 | P3 | 0.5h |
---
## 任务 1: 项目骨架搭建
**文件**
- `src/__init__.py`
- `src/main.py` - 应用入口
- `src/app.py` - QMainWindow 主窗口
- `src/gui/__init__.py`
- `src/logic/__init__.py`
- `src/core/__init__.py`
- `requirements.txt`
- `pyproject.toml`
**内容**
- 创建目录结构
- 创建空的 `__init__.py`
- `main.py` 使用 QApplication 启动
- `app.py` 创建空的主窗口框架
- `requirements.txt` 包含所有依赖
- 配置 pyproject.toml
**验收标准**
- 运行 `python src/main.py` 能启动空窗口
- 窗口标题为 "Piano Highlight Generator"
---
## 任务 2: ConfigPanel 配置面板
**文件**`src/gui/config_panel.py`
**UI 组件**
```
┌─────────────────────────────────────────────┐
│ API 配置 │
│ API Host: [________________________] │
│ API Key: [________________________] │
│ 模型: [火山方舟 Ark v] │
├─────────────────────────────────────────────┤
│ 视频配置 │
│ 视频文件: [________________] [浏览...] │
│ 输出目录: [________________] [浏览...] │
├─────────────────────────────────────────────┤
│ Whisper 配置 │
│ 模型: [large v] │
│ 模型路径: [________________] [浏览...] │
├─────────────────────────────────────────────┤
│ [开始处理] [保存配置] │
└─────────────────────────────────────────────┘
```
**信号**
- `config_changed_signal(dict)` - 配置变更时发出
**方法**
- `load_config(config: dict)` - 加载配置到 UI
- `get_config() -> dict` - 从 UI 获取配置
- `validate() -> (bool, str)` - 验证配置有效性
**验收标准**
- 所有输入框能正常输入
- 文件选择对话框能选择文件和目录
- 配置变更时发出信号
---
## 任务 3: StateManager 状态管理
**文件**`src/logic/state_manager.py`
**类**`StateManager`
**方法**
```python
def __init__(self, state_file: str):
"""初始化,加载或创建状态文件"""
def save(self):
"""保存状态到 JSON 文件"""
def get_current_step(self) -> int:
"""获取当前步骤索引 (0-6)"""
def get_step_name(self) -> str:
"""获取当前步骤名称"""
def set_step_status(self, step_name: str, status: str):
"""设置步骤状态 (pending/in_progress/completed/failed)"""
def update_clip(self, clip_index: int, **kwargs):
"""更新 clip 信息"""
def get_clips(self) -> list:
"""获取所有 clips"""
def get_user_modified_titles(self) -> dict:
"""获取用户修改过的标题 {clip_index: title}"""
def reset(self):
"""重置状态,开始新项目"""
```
**状态文件**`{output_dir}/state.json`
**验收标准**
- 创建新状态时生成默认结构
- 加载已有状态时恢复完整信息
- 保存后 JSON 文件格式正确
---
## 任务 4: ProgressView 进度视图
**文件**`src/gui/progress_view.py`
**UI 组件**
```
┌─────────────────────────────────────────────┐
│ 当前步骤: 提取视频片段 [Clip 3/14] │
│ ████████████░░░░░░░░░░░░ 50% │
├─────────────────────────────────────────────┤
│ [准备] → [提取] → [转录] → [纠正] → [字幕] │
│ → [合并] → [烧录] │
├─────────────────────────────────────────────┤
│ 日志: │
│ ┌───────────────────────────────────────┐ │
│ │ 10:30:01 开始提取片段 3/14 │ │
│ │ 10:30:02 片段 3 提取完成 │ │
│ │ 10:30:03 开始提取片段 4/14 │ │
│ └───────────────────────────────────────┘ │
├─────────────────────────────────────────────┤
│ [暂停] [停止] [继续] │
└─────────────────────────────────────────────┘
```
**信号**
- `start_signal` - 开始处理
- `pause_signal` - 暂停
- `resume_signal` - 继续
- `stop_signal` - 停止
**方法**
- `update_step(step_name: str, percent: int)` - 更新步骤进度
- `update_clip_progress(current: int, total: int)` - 更新 Clip 进度
- `append_log(message: str)` - 追加日志
- `show_titles_for_review(titles: list)` - 显示标题待审核(触发 TitleEditor
**验收标准**
- 进度条能实时更新
- 日志能自动滚动到最新
- 按钮状态能根据流水线状态变化
---
## 任务 5: Worker 后台线程
**文件**`src/logic/worker.py`
**类**`Worker(QThread)`
**信号**
```python
progress_signal = pyqtSignal(str, int, str) # step_name, percent, message
clip_completed_signal = pyqtSignal(int) # clip_index
step_started_signal = pyqtSignal(str) # step_name
step_completed_signal = pyqtSignal(str) # step_name
titles_ready_signal = pyqtSignal(list) # [{clip_index, original, llm_suggested}]
error_signal = pyqtSignal(str) # error_message
finished_signal = pyqtSignal(bool, str) # success, message
log_signal = pyqtSignal(str) # log message
```
**方法**
- `__init__(config, state_manager, controller)`
- `run()` - 执行流水线
- `request_pause()` - 请求暂停
- `request_stop()` - 请求停止
**暂停实现**
```python
def run(self):
for step in self.steps:
if self.is_stopped:
break
if self.is_paused:
self.wait_for_resume() # 等待用户resume信号
# 执行步骤...
```
**验收标准**
- UI 在处理过程中不卡顿
- 暂停信号能在 1 秒内响应
- 所有信号能正确传递到 UI
---
## 任务 6: PipelineController 流水线控制
**文件**`src/logic/pipeline_controller.py`
**类**`PipelineController`
**步骤定义**
```python
STEPS = [
'ready',
'extracting', # 提取片段
'transcribing', # 转录
'title_correcting', # 标题纠正(人工介入点)
'generating_subtitles', # 生成字幕
'merging', # 合并
'burning', # 烧录
'completed'
]
```
**方法**
```python
def __init__(self, config: dict, state: StateManager):
self.config = config
self.state = state
self.is_paused = False
self.is_stopped = False
def run(self, worker: Worker):
"""运行流水线"""
def pause(self):
"""暂停"""
def resume(self):
"""恢复"""
def stop(self):
"""停止"""
def step_extracting(self, worker: Worker):
"""提取片段"""
def step_transcribing(self, worker: Worker):
"""转录(调用 Whisper"""
def step_title_correcting(self, worker: Worker) -> list:
"""标题纠正 - 调用 LLM,返回需要用户确认的标题"""
def step_generating_subtitles(self, worker: Worker):
"""生成字幕"""
def step_merging(self, worker: Worker):
"""合并视频"""
def step_burning(self, worker: Worker):
"""烧录字幕"""
```
**验收标准**
- 每个步骤能正确执行
- 暂停/恢复能正确工作
- 状态能正确保存
---
## 任务 7: TitleEditor 标题编辑器
**文件**`src/gui/title_editor.py`
**UI 组件**
```
┌─────────────────────────────────────────────────────────────┐
│ 标题审核 - 请确认以下标题是否正确 │
├─────────────────────────────────────────────────────────────┤
│ # │ 原始标题 │ LLM建议 │ 修改后 │ 操作 │
├───┼──────────────┼─────────────┼───────────────┼──────────┤
│ 1 │ 弹奏 │ 弹奏 │ [弹奏 ] │ [编辑] │
│ 2 │ 非连奏弹奏法 │ 非连奏弹奏法 │ [非连奏弹奏法] │ [编辑] │
│ 3 │ 时值 │ 休止符 ✗ │ [休止符 ] │ [编辑] │
│ 4 │ 休止符 │ 休止符 │ [休止符 ] │ [编辑] │
│ 5 │ 节奏 │ 节奏 │ [节奏 ] │ [编辑] │
├─────────────────────────────────────────────────────────────┤
│ [全部确认] [取消] │
└─────────────────────────────────────────────────────────────┘
```
**编辑弹窗**
```
┌─────────────────────────────────┐
│ 编辑标题 - Clip #3 │
│ │
│ 原始标题: 时值 │
│ LLM建议: 休止符 │
│ │
│ 修改后: [_______________] │
│ │
│ [确定] [取消] │
└─────────────────────────────────┘
```
**信号**
- `titles_confirmed_signal(list)` - 用户确认的标题
**验收标准**
- 能显示所有标题
- 能编辑单个标题
- 能批量确认
- 确认后返回列表
---
## 任务 8: 主窗口集成
**文件**`src/app.py`
**布局**
```
┌─────────────────────────────────────────────────────────────┐
│ Piano Highlight Generator [_][□][X] │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────────┐ ┌─────────────────────────────────┐ │
│ │ │ │ │ │
│ │ 配置面板 │ │ 进度视图 │ │
│ │ ConfigPanel │ │ ProgressView │ │
│ │ │ │ │ │
│ │ │ │ │ │
│ │ │ │ │ │
│ │ │ ├─────────────────────────────────┤ │
│ │ │ │ 标题编辑器 (折叠) │ │
│ │ │ │ TitleEditor │ │
│ └─────────────────┘ └─────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ 状态: 就绪 v1.0 │
└─────────────────────────────────────────────────────────────┘
```
**集成逻辑**
1. ConfigPanel 发出 `config_changed_signal` → Controller 接收
2. 用户点击"开始" → Controller 启动 Worker
3. Worker 发出 `titles_ready_signal` → TitleEditor 显示
4. 用户确认标题 → TitleEditor 发出 `titles_confirmed_signal` → Worker 继续
5. Worker 发出 `progress_signal` → ProgressView 更新
**验收标准**
- 能启动处理
- 各组件能正确通信
- 标题编辑器在正确时机显示
---
## 任务 9: 核心模块适配
**文件**`src/core/` (复用现有模块)
**适配工作**
1. 复制 `scripts/` 下的核心模块到 `src/core/`
2. 修改 import 路径
3. 确保 `constants.py` 中的路径配置可从外部传入
4. 适配视频处理函数返回成功/失败状态
**验收标准**
- 核心模块能在 GUI 中正常调用
- 错误能被捕获并传递到 UI
---
## 任务 10: 错误处理完善
**处理场景**
| 场景 | 处理方式 |
|------|----------|
| API Key 无效 | 401 错误,提示用户检查配置 |
| 视频文件不存在 | 暂停,弹窗提示 |
| 磁盘空间不足 | 暂停,弹窗提示 |
| Whisper 模型未找到 | 提示下载或选择其他模型 |
| 处理异常 | 保存状态,显示错误日志 |
**验收标准**
- 错误不导致程序崩溃
- 错误信息清晰用户友好
- 状态正确保存
---
## 任务 11: 打包配置 + 测试
**文件**
- `nuitka_options.py`
- `build.bat` (Windows 打包脚本)
- `build.sh` (Linux/Mac 打包脚本)
**打包步骤**
1. 安装依赖:`pip install -r requirements.txt`
2. 开发测试:`python src/main.py`
3. 打包:`python -m nuitka nuitka_options.py`
4. 测试 exe`dist/PianoHighlightGenerator.exe`
**验收标准**
- 打包后体积 < 50MB
- 双击能正常运行
- 所有功能在打包后正常工作
---
## 任务 12: 文档和 README
**文件**`README.md`
**内容**
- 应用介绍和截图
- 系统要求
- 安装指南(开发安装、打包安装)
- 使用说明
- 常见问题
- 许可证
**验收标准**
- 用户能根据 README 运行应用
- 常见问题有解决方案
---
## 并行化分析
**可并行任务**
| 任务组 | 可并行任务 | 原因 |
|--------|-----------|------|
| UI 组件组 | 2, 4, 7 | 独立开发,独立 UI 组件 |
| 核心逻辑组 | 3, 5, 6 | 有依赖关系,需顺序开发 |
| 集成测试组 | 8, 10 | 依赖前面所有任务 |
**推荐开发顺序**
1. **第一波(可并行)**1, 2, 4, 7, 9
2. **第二波(依赖第一波)**3, 5, 6
3. **第三波(集成)**8, 10
4. **最后**11, 12
---
## Git 分支规划
**建议分支**
- `main` - 主分支,稳定代码
- `feat/ui` - UI 组件开发 (任务 2, 4, 7)
- `feat/core` - 核心逻辑开发 (任务 3, 5, 6)
- `feat/integration` - 集成和打包 (任务 8, 10, 11, 12)
**合并顺序**
```
feat/ui ─────────┐
feat/core ────────┼──► main
feat/integration ─┘
```