16 KiB
16 KiB
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__.pysrc/main.py- 应用入口src/app.py- QMainWindow 主窗口src/gui/__init__.pysrc/logic/__init__.pysrc/core/__init__.pyrequirements.txtpyproject.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)- 加载配置到 UIget_config() -> dict- 从 UI 获取配置validate() -> (bool, str)- 验证配置有效性
验收标准:
- 所有输入框能正常输入
- 文件选择对话框能选择文件和目录
- 配置变更时发出信号
任务 3: StateManager 状态管理
文件:src/logic/state_manager.py
类:StateManager
方法:
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)
信号:
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()- 请求停止
暂停实现:
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
步骤定义:
STEPS = [
'ready',
'extracting', # 提取片段
'transcribing', # 转录
'title_correcting', # 标题纠正(人工介入点)
'generating_subtitles', # 生成字幕
'merging', # 合并
'burning', # 烧录
'completed'
]
方法:
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 │
└─────────────────────────────────────────────────────────────┘
集成逻辑:
- ConfigPanel 发出
config_changed_signal→ Controller 接收 - 用户点击"开始" → Controller 启动 Worker
- Worker 发出
titles_ready_signal→ TitleEditor 显示 - 用户确认标题 → TitleEditor 发出
titles_confirmed_signal→ Worker 继续 - Worker 发出
progress_signal→ ProgressView 更新
验收标准:
- 能启动处理
- 各组件能正确通信
- 标题编辑器在正确时机显示
任务 9: 核心模块适配
文件:src/core/ (复用现有模块)
适配工作:
- 复制
scripts/下的核心模块到src/core/ - 修改 import 路径
- 确保
constants.py中的路径配置可从外部传入 - 适配视频处理函数返回成功/失败状态
验收标准:
- 核心模块能在 GUI 中正常调用
- 错误能被捕获并传递到 UI
任务 10: 错误处理完善
处理场景:
| 场景 | 处理方式 |
|---|---|
| API Key 无效 | 401 错误,提示用户检查配置 |
| 视频文件不存在 | 暂停,弹窗提示 |
| 磁盘空间不足 | 暂停,弹窗提示 |
| Whisper 模型未找到 | 提示下载或选择其他模型 |
| 处理异常 | 保存状态,显示错误日志 |
验收标准:
- 错误不导致程序崩溃
- 错误信息清晰用户友好
- 状态正确保存
任务 11: 打包配置 + 测试
文件:
nuitka_options.pybuild.bat(Windows 打包脚本)build.sh(Linux/Mac 打包脚本)
打包步骤:
- 安装依赖:
pip install -r requirements.txt - 开发测试:
python src/main.py - 打包:
python -m nuitka nuitka_options.py - 测试 exe:
dist/PianoHighlightGenerator.exe
验收标准:
- 打包后体积 < 50MB
- 双击能正常运行
- 所有功能在打包后正常工作
任务 12: 文档和 README
文件:README.md
内容:
- 应用介绍和截图
- 系统要求
- 安装指南(开发安装、打包安装)
- 使用说明
- 常见问题
- 许可证
验收标准:
- 用户能根据 README 运行应用
- 常见问题有解决方案
并行化分析
可并行任务:
| 任务组 | 可并行任务 | 原因 |
|---|---|---|
| UI 组件组 | 2, 4, 7 | 独立开发,独立 UI 组件 |
| 核心逻辑组 | 3, 5, 6 | 有依赖关系,需顺序开发 |
| 集成测试组 | 8, 10 | 依赖前面所有任务 |
推荐开发顺序:
- 第一波(可并行):1, 2, 4, 7, 9
- 第二波(依赖第一波):3, 5, 6
- 第三波(集成):8, 10
- 最后: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 ─┘