# Chengfeng Visual

> 给剪好的口播配画面：在录屏上盖 HTML 层（圈重点标注 / 小黑整屏动画 / 推近），层绑字幕屏、由播放器逐帧驱动、直接在预览里看。用户说做分镜、配画面、加动画、圈重点、B-roll、做 storyboard 时使用。不要用于删词剪辑、字幕、物理剪切或成片渲染。

- Skill: `gabrielmoreira/chengfeng-visual` (Agent Skill)
- Install (CLI): `npx skillmds@latest add gabrielmoreira/chengfeng-visual`
- Raw SKILL.md: https://api.skillmd.com/api/skills/gabrielmoreira/chengfeng-visual/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: gabrielmoreira (https://skillmd.com/u/gabrielmoreira)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/gabrielmoreira/chengfeng-visual

---


# 画面（分镜）

**这是一件事，不是流程的一段。** 用户什么时候喊它就什么时候做，改完剪辑可以回来再做。

前提只有两个：**账本和字幕已经存在**（层按字幕屏放、时间从账本算）。

```text
需要   edit-list.json、transcript.json、subtitles.json
产出   visuals.json + modules/<序号-名字>/index.html
```

干完就停，**不指挥用户下一步**。

先读取并执行 [业务 Skill 的阶段合同](../../references/business-workflow-contract.md)。
模块写法的硬规矩见 [模块契约](references/visual-module-contract.md)，
判断规则见 [画面判断](references/visual-judgment.md)。

## 0. 就绪

先执行 [检查更新](../chengfeng-check-updates/SKILL.md) 的「就绪检查」——skills 是否
最新、Runtime 是否配套；**插件根**也在那里定位（本文命令里的 `<插件根>` 都代入
那个字面路径）。只有「就绪」才继续；「需新会话」或「停」按它的处置执行
（含「禁止自制替代界面」禁令），业务 Skill 不自带环境逻辑。

若就绪结果为 `runtime.kind=desktop-managed`，直接复用桌面 App 已安装的稳定 CLI 与
同一 `launchd/windows-task` 服务；不要解析 Electron 路径、另装依赖或起第二个
Runtime。

## 命令

```bash
node "<插件根>/scripts/ensure-running.cjs" --json
node "<插件根>/scripts/videocut-cli.cjs" visual get   <project> --json
node "<插件根>/scripts/videocut-cli.cjs" visual frame <project> --cues sub-0004,sub-0005 --count 12 --out <dir> --json
node "<插件根>/scripts/videocut-cli.cjs" visual add   <project> --module modules/01-xx/index.html --cues sub-0004,sub-0005 [--zoom x,y,w,h] [--id vis-0001] --json
node "<插件根>/scripts/videocut-cli.cjs" visual remove <project> --id vis-0001 --json
```

`ensure-running` 必须先证明 canonical 5190 属于当前平台的托管服务；失败就透传并
停止，不回退 foreground 或自选端口。

层绑**字幕屏**（`--cues`），产品自己换算成词 id——层永远不可能绑上没人说的词，
剪辑变了层自己跟着挪。**不存秒数。**

## 四步，一步不跳

```text
① 文字定任务    读 subtitles.json，按语义分段，每段回答：
               教程/演示/证明，还是概念/逻辑/过渡？
② 抽帧看画面    visual frame 抽 8-12 帧，真的用眼睛看。
               实测 12 段里有 2 段被画面推翻文字预判 —— 这步不是走形式
③ 量运动窗口    相邻帧做像素差，找出滚动/切换/操作的时刻。
               层只盖稳定窗口，圈在画面开始动之前退场
④ 做层放层     写模块 → visual add → 在预览里逐层核对
```

### ② 的判断规则

```text
画面正是他说的东西     → 标注：圈住、说到哪个词圈哪里。真证据不许盖
画面弱相关/空白       → 小黑动画：整屏白底，从风格库做
画面自身足够清楚      → 不动。这是最常见的正确答案（实测 13 段里 4 段不动）
```

### ③ 的产出物是数字，不是感觉

```text
圈的坐标      像素统计量出来（灰度扫描找文字行），不许目测 —— 目测差过 50px
互动时刻      逐帧像素差找突变（实测一次从 4 跳到 335），圈在它之前 0.2s 退完
稳定窗口      开头常有滚动（他在找内容），层从停稳那屏的 cue 开始绑
```

## 推近（zoom）用之前先想

```text
默认不推近。   960x720 的录屏放大就糊，用户会立刻看出来
非推不可时     ≤1.6 倍、区域取 62.5% 见方居中 —— 构图完整 > 读清小字
字太小读不清   用圈引导视线就够了；真要读清，答案是高分辨率重录，不是放大
```

## 审阅循环

模块目录用**序号命名**（`01-daily-report`、`05-anim-task-split`），
时间线轨道上显示目录名，用户报号你改那一层，别的不动。

两条改层纪律，各对应一次真事故：

```text
改层必查模块     层收窄/延长后，模块里写死的相对时刻不会跟着变 ——
                圈的出场时刻可能落到层结束之后，永远不出现
验收看像素      截图看画面，不查 DOM 属性。「可见性翻转正确」的 iframe
                曾经物理上不在画面里 —— 属性全对、屏幕全空
```

## 不许做什么

- 不许跳过抽帧和运动窗口直接做（两种错各犯过一次：盖掉真证据、圈悬在滚动上）
- 不许把每段都做点什么——铺满不是目标，不动是常见答案
- 不许存秒数、不许目测坐标、不许在白底页面上加压暗
- 没有真实内容不许拿占位图充数
- 风格从注册表选，不得凭空发明
- **品牌图标用官方字形，不许手画替身**（X 用两笔交叉线画过，被用户抓了）。
  本地索引没有的，从 simple-icons 取单色官方 glyph（黑白风格正好配），
  原 svg 存进模块目录备查；同一条片里同一品牌只能长一个样

