Files
skills/piano-lesson-highlight-generator/STATUS.md
T
hmo 04db423416 Initial commit: skills library
- 70 skills with code and documentation
- Add .gitignore (ignore __pycache__, output/, temp/, venv/)
- Clean up test intermediates and caches
2026-04-26 19:27:40 +08:00

227 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 📋 钢琴课精华视频生成技能 - 会话状态与交接文档
> **生成时间**: 2026-04-02
> **最后更新**: 2026-04-03
> **当前状态**: ✅ 全流程验证通过,环境配置已固化
---
## 🎯 核心目标
利用 `piano-lesson-highlight-generator` 技能,根据 PPT 和视频自动生成精华视频(<15分钟),包含标题卡、字幕、转场。
---
## 🔧 环境配置
**详见 `ENVIRONMENT.md`**
关键信息:
- **Python 环境**: `D:/ProgramData/anaconda3/envs/py312_cuda/python.exe`Python 3.12.13
- **PyTorch**: 2.5.1+cu121**必须 GPU**CPU 会超时)
- **Whisper 模型**: `D:/AI/LM-Models/faster-whisper/large-v3/`
- **运行命令**: 直接使用完整路径调用 Python,不要用 `conda activate`
### 环境验证
```bash
"D:/ProgramData/anaconda3/envs/py312_cuda/python.exe" -c "import torch; print(torch.cuda.is_available())"
# 必须输出 True
```
---
## 📊 已解决的结构性问题
### 1. 知识点匹配错误(核心修复)
| 问题 | 根因 | 修复方案 | 状态 |
|------|------|----------|------|
| 匹配到导读区而非教学区 | 搜索词按顺序匹配,找到第一个就 break;评分只看密度 | 完整关键词+核心子词+相关词映射+数字归一化收集所有 segment;评分综合考量出现次数、文本量、讲解密度、孤立程度 | ✅ |
| 匹配到回顾区而非教学区 | 回顾区有更多相关 segment | 靠近作业时间惩罚 + 回顾性语言检测("刚才"、"刚刚"等) | ✅ |
| 匹配到"等下再说"而非实际教学 | 预告和实际教学无法区分 | 预告/讲解特征词检测;推迟语言检测;导读过滤(无讲解 + segment ≤ 2 → 跳过) | ✅ |
| 通用词误匹配(如"记号"匹配到无关内容) | 搜索词包含 2 字通用词 | 通用后缀过滤(记号、符号、音符等不单独匹配);相关词映射 | ✅ |
| 数字不匹配("十六分音符"≠"16分音符" | Whisper 将中文数字识别为阿拉伯数字 | 数字归一化匹配(中文数字↔阿拉伯数字互转) | ✅ |
| "掀起你的盖头来"只在导读出现 | 转录中未出现该歌曲名 | 导读过滤:无讲解特征 + segment ≤ 2 → 跳过 | ✅ |
### 2. 字幕同步问题
| 问题 | 根因 | 修复方案 | 状态 |
|------|------|----------|------|
| 字幕 1分18秒开始乱套 | clip3/clip4 重叠导致 JSON 内容重复,偏移计算用 config duration 而非实际 segments end | 偏移改用 JSON segments 实际最大 end 时间 | ✅ |
| 字幕滞后 2-3 秒 | 转录过滤包含跨边界片段,调整后的时间戳超出 clip 实际时长 | 限制时间戳在 clip 实际时长范围内 | ✅ |
| clip2(延音线)被跳过 | Whisper 把"延音"识别为"言音",内容验证失败 | 内容验证时先应用术语纠正(言音→延音、演音→延音等) | ✅ |
### 3. 作业片段匹配
| 问题 | 根因 | 修复方案 | 状态 |
|------|------|----------|------|
| 作业片段匹配不到 | 引导语列表不全 | 用"作业"词密度替代引导语匹配 | ✅ |
| 作业片段截断太早 | detect_gap_cutoff 对作业场景太敏感 | 间隔阈值从 15s 放宽到 30s;视频末尾前 2 分钟兜底 | ✅ |
| 作业结束不准确 | 无法识别口语化结束表达 | 模糊匹配 30+ 种口语表达("作业.*就这样"、"作业.*就这些"、"下课"等) | ✅ |
### 4. 去重逻辑优化
| 问题 | 根因 | 修复方案 | 状态 |
|------|------|----------|------|
| 多个知识点在同一区域被丢弃 | 去重逻辑只保留密度最高的,丢弃其他 | 调整边界让相邻知识点共存,而非丢弃 | ✅ |
### 5. GPU 资源管理
| 问题 | 根因 | 修复方案 | 状态 |
|------|------|----------|------|
| 僵尸进程占用 GPU 显存 | 多次启动转录进程,旧进程未释放 | 转录后 `del model` + `gc.collect()` + `torch.cuda.empty_cache()` | ✅ |
| `taskkill` 自杀命令 | 清理命令杀掉了当前进程 | 移除转录前的 taskkill,改为转录后显式释放模型 | ✅ |
---
## 🏗️ 知识点匹配架构
### 评分公式
```
score = (base_score + full_bonus) × text_bonus × isolation_penalty × teaching_bonus × review_penalty × defer_penalty × preview_penalty
```
| 因子 | 计算方式 | 作用 |
|------|---------|------|
| base_score | total_count × avg_rel | 相关 segment 数量 × 平均相关度 |
| full_bonus | full_count × 2.0 | 完整关键词出现次数奖励 |
| text_bonus | min(total_text_len / 30, 5.0) | 上下文文本量加成 |
| isolation_penalty | 1.0 / (1.0 + other_kw_count × 0.5) | 和其他知识点一起出现惩罚 |
| teaching_bonus | 1.0 + teaching_density × 2.0 | 讲解词占比加成 |
| review_penalty | max(0.1, time_to_homework / 300) | 靠近作业时间惩罚 |
| defer_penalty | max(0.1, 1.0 - defer_ratio × 2.0) | 推迟语言惩罚 |
| preview_penalty | max(0.1, 1.0 - preview_ratio × 2.0) | 预告语言惩罚 |
### 相关度评分
| 匹配类型 | 分数 | 示例 |
|---------|------|------|
| 完整关键词 | 3.0 | "附点音符" 匹配 "附点音符" |
| 数字归一化 | 2.5 | "十六分音符" 匹配 "16分音符" |
| 核心子词 | 2.0 | "双音的支撑" 匹配 "双音支撑" |
| 相关词映射 | 1.5 | "升降记号" 匹配 "升号"/"降号" |
| 前缀匹配 | 1.5 | "附点音符" 匹配 "附点" |
| 核心词 | 1.0 | 3-4 字核心词匹配 |
### 相关词映射
```python
related_terms = {
"升降记号": ["升号", "降号", "升记", "降记", "升降", "升半", "降半"],
"还原记号": ["还原"],
"附点音符": ["附点"],
"延音线": ["延音", "同音连线"],
"双音的支撑": ["双音", "支撑"],
"婚礼进行曲": ["婚礼"],
"掀起你的盖头来": ["盖头来", "盖头", "掀起"],
"十六分音符": ["16分", "十六分"],
"八分音符": ["8分", "八分"],
}
```
### 特征词检测
| 类型 | 关键词 |
|------|--------|
| 推迟语言 | "等下再说"、"等下讲"、"后面再说"、"稍后再说"、"先不说" |
| 预告语言 | "先说一下"、"先讲一下"、"首先说"、"我先说"、"提一下" |
| 讲解语言 | "因为"、"所以"、"就是"、"什么意思"、"为什么"、"怎么"、"比如说"、"大家看"、"弹"、"按"、"练" |
| 回顾语言 | "刚才"、"刚刚"、"今天学"、"今天讲"、"回顾"、"练习一下"、"复习" |
### 作业结束检测(模糊匹配 30+ 种表达)
| 类型 | 匹配模式 | 示例 |
|------|---------|------|
| 明确下课 | `下课``拜拜``再见` | "下课" |
| 作业完成 | `作业.*就这样``作业.*就这些``作业.*讲到这里` | "今天的作业就这样"、"关于作业就讲到这里" |
| 通用结束 | `就到这里``就这样了``说完了``没什么.*说的` | "就这些了"、"没什么要说的了" |
| 群发通知 | `发群``到时候.*发` | "到时候我发群里" |
---
## 📂 项目目录结构
```
projects/piano-lesson-highlights/
├── data/ # 原始输入数据
│ ├── lesson2/
│ │ ├── video.mp4
│ │ └── course.pptx
│ └── lesson3/
│ ├── video.mp4
│ └── course.pptx
└── cases/ # 每个案例的工作区
├── lesson2/
│ ├── config.yaml
│ ├── intermediates/
│ │ └── full_transcript.json
│ └── output/
│ ├── v1_final.mp4
│ └── subs/
└── lesson3/
├── config.yaml
├── intermediates/
│ └── full_transcript.json
└── output/
├── v1_final.mp4
└── subs/
```
---
## ✅ lesson2 验证结果
| # | 知识点 | 匹配位置 | 实际内容 | 状态 |
|---|--------|---------|---------|------|
| 1 | 附点音符 | 3126s (52min) | 实际教学区 | ✅ |
| 2 | 延音线 | 4040s (67min) | 实际教学区 | ✅ |
| 3 | 升降记号 | 4237s (70min) | 实际教学区 | ✅ |
| 4 | 还原记号 | 4682s (78min) | 实际教学区 | ✅ |
| 5 | 双音的支撑 | 5051s (84min) | 实际教学区 | ✅ |
| 6 | 婚礼进行曲 | 5345s (89min) | 实际教学区 | ✅ |
| 7 | 作业 | 6515s-6998s (482s) | 作业区 | ✅ |
**产出**
- v1_final.mp4: 679秒(11.3分钟),133.3 MB
- 380 条字幕(original/terms/ai 三个版本)
---
## ✅ lesson3 验证结果
| # | 知识点 | 匹配位置 | 实际内容 | 状态 |
|---|--------|---------|---------|------|
| 1 | 八分音符 | 2332s (38min) | 实际教学区 | ✅ |
| 2 | 十六分音符 | 2456s (40min) | 实际教学区(数字归一化匹配) | ✅ |
| 3 | 反复记号 | 3296s (54min) | 实际教学区 | ✅ |
| 4 | 高八度 | 3315s (55min) | 实际教学区 | ✅ |
| 5 | 低八度记号 | 3369s (56min) | 实际教学区 | ✅ |
| 6 | 作业 | 5272s-5981s (709s) | 作业区(下课 5951s + 30s | ✅ |
| ❌ | 掀起你的盖头来 | 已跳过 | 只在导读出现,无实际教学 | ✅ 正确跳过 |
**产出**
- v1_final.mp4: 867秒(14.5分钟),69.8 MB
- 417 条字幕(original/terms/ai 三个版本)
---
## ⏳ 待处理
| 项目 | 状态 | 说明 |
|------|------|------|
| 字幕 AI 纠错验证 | 待人工 | 老莫需要看 v1_ai.srt 的纠错效果 |
| 视频质量审核 | 待人工 | 老莫需要看 v1_final.mp4 确认标题卡、转场、字幕同步 |
---
## 💡 关键经验
1. **转录数据可复用**:同一节课的 `full_transcript.json` 可以直接复制使用,不需要重新转录
2. **GPU 是必须的**:CPU 转录 100 分钟视频会超时(100+ 分钟),GPU 约 20-30 分钟
3. **术语纠正很重要**Whisper 会把"附点"识别为"副点"、"延音"识别为"言音"等
4. **教学 vs 导读 vs 回顾**:需要综合多种特征才能准确区分,单一指标不可靠
5. **数字归一化**:Whisper 可能将中文数字识别为阿拉伯数字("十六"→"16"),需要双向匹配
6. **作业结束检测**:老师口语表达多样,必须用模糊匹配覆盖 30+ 种表达
7. **GPU 资源管理**:转录完成后必须显式释放模型,否则显存泄漏