Files

16 KiB
Raw Permalink Blame History

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

方法

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 │
└─────────────────────────────────────────────────────────────┘

集成逻辑

  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. 测试 exedist/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 ─┘