# 关键决策记录

## 2026-05-12

### UI 架构演进（被用户多次调整）
1. ❌ 初版：上下流式 04 暗色画廊 → 否决
2. ❌ 横向小节点紧凑 DAG（10 节点）+ stage bar 顶部 → 用户要换方向
3. ❌ Storyflow 大节点列式 + mini DAG 拓扑底部 → 用户说"理解错了"
4. ❌ 顶部看板（看板每列对应节点）→ 用户嫌太扎眼
5. ❌ 折叠看板（点击展开）→ 多选展开 → 改回单选展开
6. ✅ **侧面 sidebar（108px）+ drawer 弹出**（最终）

### 节点合并
- 用户："输入/下载/拆分 三合一" → input 节点吃下 download + split 的信息和状态
- 原 10 节点 → 8 节点

### 视觉决策
- Kanban 风格（不是 Apple 04 暗色画廊）
- 4 类型颜色：input 紫蓝 / process 橙 / ai 紫粉 / output 翠绿
- 关键帧节点改为 process 类型（橙），因为不调模型（只 ffmpeg）
- mini-card 内嵌：玻璃质感 + 渐变 + 圆角 + 深阴影

### 关键帧选取算法（D 启发式）
1. ffmpeg 均匀采样 30 张候选（fast seek）
2. pHash 去重相似帧（汉明距离 < 8）
3. Laplacian variance 评分清晰度（手写 numpy，不用 scipy）
4. 时序分桶 n 等分，每桶取最清晰
5. 输出 5 张

不用场景切换检测（太慢，且 TK 一镜到底视频抓不出来）。

### 抽帧 ffmpeg 参数（重要坑）
```
ffmpeg -y -ss <t> -i source.mp4 \
  -frames:v 1 \
  -pix_fmt yuvj420p \    # ⚠️ mjpeg 不支持 yuv420p
  -q:v 3 \
  out.jpg
```

### 视频缩略图设计
- Input 节点上方：每个 job 一个 80px 缩略图浮条 + 「+」按钮再上传
- hover：自动播放视频片段（muted loop）
- click：node 上方 360px 展开 controls + 加帧按钮（不全屏）

### 关键帧缩略图设计
- 浮条 grid-cols-5（超过 5 张换行向上扩展）
- aspectRatio 跟视频原比例（竖屏 9:16 / 横屏 16:9 自适应）
- hover：弹 KEYFRAME_WIDTH*2 静态大图（**不放视频，因为关键帧是垫图素材**）
- click：打开 keyframe drawer 内的 lightbox

### Lightbox 嵌入策略
- 浮动 fixed 模式被否决（"全屏太遮挡"+"切换累"）
- 最终：嵌入 keyframe sidebar drawer，drawer 宽度自适应（400 / 760）
- 颜色顶栏用 TYPE_GRAD["process"] 橙红渐变，跟 keyframe tile 同色系

### Vision identify 结果结构
```json
{
  "scene": "一句话场景",
  "objects": [{"name", "position", "color", "extract_prompt"}],
  "style": "风格 / 打光 / 色调",
  "suggested_prompt": "完整英文 prompt"
}
```

下游生图直接拿 suggested_prompt 作 base prompt + 用户的正向/负向 prompt。

### 生图正负 prompt 拼合
```
{画面描述}. Include: {正向}. Do NOT include: {负向}.
Output must be clean without any watermark, username text, or platform logo.
```

默认 negative：「水印, @用户名, TikTok logo, 平台文字, 浮水印」 → 直出"纯净图"。

## 关键架构选择

### 多 job 支持
- jobs: Job[] state
- activeJobId 切换 active
- URL: `?job=id1,id2,id3` 持久化所有
- 提交链接 / 上传 → push 新 job + setActive

### 状态机
```
created → downloading → downloaded（停，等用户点解析）
       → splitting → frames_extracted
       → transcribing → transcribed | failed
```

「解析」按钮是关键的人工触发点（不是全自动），用户能选择性跑。

## 仍未解决的设计问题
- 区域化修图（inpainting）UI 没定（A 纯 prompt / B 矩形 / C 画笔 / D SAM）
- 多 job 并发轮询逻辑（当前只 active job 轮询）
- 生图结果选用后怎么传到 video gen 节点（数据流）
