shot2clip · 截图 → 文案 → 成片
一条龙:读图提炼文案 → 用户确认 → 确认素材(logo / 背景)→ 用截图渲染视频。
两个现成能力拼起来用,本 skill 只做编排和确定性转换:
| 环节 | 由谁干 |
|---|---|
| 提炼卖点、写口播文案 | screenshot-feature-copy(内置在 vendor/) |
| 文案 → spec.json(含时间轴、版式自适应) | 本 skill 的 scripts/make_spec.py |
| 逐帧渲染 + 配音 + BGM | shortvideo-studio(内置在 vendor/) |
| 默认 LOGO / 背景 | 本 skill 的 assets/:ZMX 图标 + 1080×1920 深蓝科技底(由代码现场生成,包里不含图片) |
依赖怎么来
优先用本 skill 内的 vendor/,其次才找全局安装的 skill。 这样这个包被谁下载都能直接跑,
不依赖对方机器上装过什么:
vendor/screenshot-feature-copy/GUIDE.md 文案规则 + references/template.md(第 1 阶段读这里)
vendor/shortvideo-studio/scripts/ 渲染引擎(render.sh 自动优先用这里)
> GUIDE.md 就是上游的 SKILL.md,改个名是为了不被当成两个独立技能。来源与更新方式见 vendor/README.md。
scripts/render.sh 的查找顺序:vendor/ → $SHORTVIDEO_HOME → ~/.workbuddy/skills/... → ~/.claude/skills/...。
只有「vendor 被删了」或「想改用全局最新版」时才需要额外安装,用 scripts/ensure_deps.sh --install 兜底。
维护:覆盖上游副本后必须重跑品牌替换
vendor/ 是上游快照,不是软链接。更新时 cp 覆盖会把真实产品名和它的宣传口号一起带回来,
所以覆盖完必须再做两件事,缺一步这个包就会替别人的产品做背书:
# 1) 品牌名换回占位名 ZMX AI(先替长串再替短串,否则会产出 ZMXAI 这种粘连)
grep -rl '<上游真实品牌名>' . | xargs sed -i 's/<上游真实品牌名>AI/ZMX AI/g; s/<上游真实品牌名>/ZMX/g'
# 2) 示例句里的产品口号也要换:品牌名好找,口号不会自己暴露
grep -rn 'ZMX' . | grep -v 'ZMX-icon\|ZMX-mark'
第 2 步不能省。口号按当时措辞判断,换成与该条示例功能一致的中性表述(例:本地出图,素材不上传)。
来源、版本记录与完整更新命令见 vendor/README.md。
硬性约束
- 文案没确认,不出片。 第 1 阶段产出文案后必须停下来等用户明确说通过,不要"顺手"渲染。
- 素材没确认,不出片。 出片前必须问一句要不要换 logo / 背景;没问就渲染等于替用户做了决定。
用户不换就用默认素材,不要自作主张改动assets/。 - 画面用原始截图,不用 AI 生图。 产品界面必须像素级保真,生成式模型会把界面文字画烂。
- 只改 brief.json 再重跑,不要手改 spec.json。 时间轴和版式是算出来的,手改会和配音错位。
前置检查(首次跑先跑这个)
SKILL_DIR=~/.workbuddy/skills/shot2clip
bash "$SKILL_DIR/scripts/ensure_deps.sh" # 只诊断
bash "$SKILL_DIR/scripts/ensure_deps.sh" --install # 缺啥补啥
它会逐项检查 Python 包、ffmpeg、vendor 里的两个上游技能、默认素材、中文字体,并打印可直接复制的安装命令。
缺 Python 包或 ffmpeg 时不要硬跑,中途会在渲染到一半时才报错,白等几分钟。
默认素材是「生成出来的」,包里没有图片
SkillHub 发布接口拒收二进制文件(图片会返回 400 不允许的文件类型),所以本 skill 随包分发的是
能生成图片的代码,而不是图片本身。首次跑 make_spec.py 或 render.sh 时会自动补齐:
| 文件 | 怎么来的 |
|---|---|
assets/background.jpg |
scripts/make_default_assets.py 程序化绘制,随机种子固定,逐字节可复现 |
assets/logo.png |
scripts/logo_data.py 里的 base64 还原(品牌图形无法重画,只能内嵌) |
python scripts/ensure_assets.py # 缺啥补啥(渲染流程会自动调用)
python scripts/ensure_assets.py --check # 只检查,缺失退出码 1
python scripts/ensure_assets.py --force # 强制恢复默认素材
换 LOGO 的正确流程是 make_logo.py → embed_logo.py(刷新 base64 与 SHA256)→ ensure_assets.py --check,
不要只换 assets/logo.png:那个文件是生成物,下次 --force 或别人安装后都会回到内嵌版本。
发布(上传到 SkillHub)
本地跑过渲染后 assets/ 里就有图片,直接 skillhub publish . 会被 400 拒绝。用内置脚本发布,
它会先生成一份只含文本的暂存目录:
python scripts/publish.py -m "这次改了什么" # 加 --dry-run 只本地预检
第 1 阶段:读图 → 文案
- 逐张
ViewImage读用户上传的截图,只取图上真实出现的功能名、说明文字、模型名、按钮文案。 - 按
vendor/screenshot-feature-copy/GUIDE.md的流程产出文案,模板与反例在同目录references/template.md。
若系统里已装同名的全局 skill(screenshot-feature-copy),内容一致,直接用 Skill 工具调用也可以。 - 输出格式固定:
```
还在为{痛点},{痛点2}?大量时间{和预算}都被消耗!
试试{产品名} {模块名},{定位}全流程:
- 功能名:一句话说明 ×4~5 条
```
- 顺带把口播稿写出来(屏幕上不放全文),每段 1 句,跟功能点一一对应:
第1句(对应功能1):{把这条功能念成一句人话,≤22 字}
...
落版句:{品牌+一句话总结,≤20 字}
- 输出后停下,问用户:"文案确认吗?要改哪句?确认后我开始出片。"
第 2 阶段:文案 → brief.json
用户确认后,在工作目录写 brief.json(字段全部可省略,除 images / points / voice):
{
"output": "20261028_v1.mp4",
"brand": "ZMX AI",
"hook": ["还在为一天几十张配图按次付费", "客户形象也不敢往云端传"],
"subtitle": "零成本跑通高频出图全流程",
"images": ["/path/to/1.png", "/path/to/2.png"],
"points": [["本地部署", "ComfyUI 跑在自己电脑,数据不出本机"]],
"outro_lines": ["一个页面,搞定找词、生图、排版、归档"],
"voice": ["第1句", "第2句", "落版句"],
"voice_name": "zh-CN-YunxiNeural",
"latin": { "AI": "诶爱" }
}
> 上面的「ZMX AI」是占位产品名(和本 skill 的 logo 同源,方便对照),其中的功能描述只为说明字段格式;
> 换项目时整体替换成目标产品,不要连品牌名一起照搬。
映射规则(详见 references/spec-mapping.md):
| brief 字段 | 屏幕上的位置 | 长度红线 |
|---|---|---|
hook |
顶部黄色色块,1~2 行 | 每行 ≤14 字 |
subtitle |
红色副标题条 | ≤16 字 |
images |
中部截图卡片,按顺序轮播 | 张数 = voice 句数 |
points |
底部卖点条 | 标签 ≤5 字,说明 ≤18 字 |
outro_lines |
落版正文 | ≤4 行,每行 ≤26 字 |
voice |
配音,最后一句是落版 | 每句 ≤22 字 |
images与points数量不必相等:图少就一图对应多条,图多就只挑最能说明问题的那几张。- 配音不要逐字念屏幕上的所有字,否则语速会失控。
- 文案里有
AI/GPT/APP时,用latin映射只改朗读、不改屏幕(AI→诶爱)。
第 3 阶段:素材确认(出片前必做)
文案过了之后、跑 make_spec.py 之前,必须先把这句话问出去:
> 画面默认用「ZMX 图标 + 深蓝科技背景」,要换吗?不换我就直接出片了。
三种答复的处理:
| 用户说 | 怎么做 |
|---|---|
| 不换 / 就用默认 / 随便 | 什么都不做。make_spec.py 会自动把 assets/logo.png、assets/background.jpg 拷到工作目录 |
| 换 logo | 把用户给的图存成工作目录里的 logo.png(正方形,≥512px,透明底或白底都行),别覆盖 assets/ 里的默认图 |
| 换背景 | 存成工作目录里的 background.jpg(9:16,≥1080×1920),同样别动 assets/ |
- 默认素材长什么样:logo 是 ZMX 图标(560×560 透明底,深色圆角方块 + 白色图形);
背景是 1080×1920 深蓝科技底。两者都由scripts/ensure_assets.py现场生成,首次跑渲染时自动补齐。换图成本低,直接问就好。 - 工作目录里的同名文件优先级高于
assets/,所以改素材永远放在工作目录,默认图保持原样,下一个项目才不会串味。 - 用户没回应素材这一项、只催出片时,按默认走,并在交付时明说「用了默认 logo 和背景」。
第 4 阶段:出片
cd "$SKILL_DIR"
python scripts/make_spec.py /path/to/brief.json --outdir "/path/to/video/20261028_图片工坊"
bash scripts/render.sh "/path/to/video/20261028_图片工坊"
make_spec.py 会打印时长、分段、卡片比例,并把所有风险以 WARN 打出来——逐条读,
尤其是「卖点条过长」「hook 偏长」「拉丁缩写」这三类。
只改配音、画面不动时(改一句话、换音色):
SKIP_RENDER=1 bash scripts/render.sh "<同一目录>"
渲染完成后打开三张自检帧 check_01_head.png / check_02_mid.png / check_03_outro.png:
- 顶部色块文字左右留白是否对称(行尾带标点时最容易偏)
- 截图卡片有没有压到卖点条,卖点第 5 条有没有被顶出画面
- 落版 LOGO 圆角是否干净、有没有被拉变形,品牌名和正文有没有重叠
有问题就改 brief 重跑,不要手动改 spec。
交付
- 成片命名
YYYYMMDD_vN.mp4(vN 写在brief.output里) - 一起给出:成片路径、文案正文、时长、自检帧,以及这一版用的 logo 与背景(默认还是用户自己给的)
- 用户要换背景/换 LOGO:把新图以同名文件放进工作目录(
logo.png/background.jpg),
重跑即可;只有想长期改默认值时才动assets/
常见问题
| 现象 | 原因 | 处理 |
|---|---|---|
报 asset not found: background.jpg |
默认资产没落到工作目录 | 跑 python scripts/ensure_assets.py,再确认 make_spec.py 跑过(它会拷贝 assets) |
| 截图被裁掉了左右 | 卡片比例比截图窄 | 不用管:make_spec.py 已按 contain 补边,不裁内容 |
| 某句配音赶读 | 该句字数超出时间槽 | 精简该句,别提高全局语速 |
AI 被读成「爱」 |
中文 TTS 吃拉丁缩写 | 在 brief.latin 里加映射 |
| 卖点条压到落版 | 5 条 + 说明太长 | 说明压到 18 字内,或减到 4 条 |
| 改完文案节奏变慢/变乱 | 改了 spec 没重算时间轴 | 重跑 make_spec.py,它会重排所有切点 |
| 报「找不到渲染引擎」 | vendor/shortvideo-studio 被删且未全局安装 |
bash scripts/ensure_deps.sh --install,或 SHORTVIDEO_HOME 指向已有副本 |
找不到 vendor/screenshot-feature-copy |
安装包不完整 | 第 1 阶段退化成本 SKILL.md 里的精简规则也能写,但质量下降;建议重装 skill |
| 渲染中途才报缺 ffmpeg | 跳过了前置检查 | 先跑 ensure_deps.sh,别等渲染到一半 |
| 落版 logo 还是旧的 | 工作目录里残留上次的 logo.png,make_spec.py 不会覆盖已有文件 |
删掉工作目录里的 logo.png / background.jpg 再重跑 |
| 换了 logo 但成片没变 | 改的是 assets/,而工作目录已有同名文件(优先级更高) |
改工作目录那份,或删掉工作目录那份 |
| logo 边缘发黑/发灰、或带一圈白边 | 用户给的是带底色的 jpg,不是透明 png | 换成透明底 png;只有白底素材时用 scripts/make_logo.py 的 alpha 反推流程裁出图形 |