Communitygithub.com

REEL-FROM-SCRIPT · v7

根据你未编写的脚本、需要逆向分析的参考素材,以及一个毫无历史记忆的全新对话,生成一段9:16竖屏短片——它看起来经过精心导演,且绝不会出现制作事故。

REEL-FROM-SCRIPT · v7 是什么?

REEL-FROM-SCRIPT · v7 是一个高度结构化的 AI 智能体技能,专为在全新对话中从零开始生成 9:16 竖屏短片(Reel)而设计。其核心承诺是:唯一需要人工编辑的文件是 `PARAMS.json`,而 `prepare.py` 和 `qc.py` 是唯一有权说“不”的程序;其余所有内容均由脚本生成,且通过一个命令可完全复现。该技能封装了一套严格的设计规则(七法则),涵盖网格布局、颜色循环、排版、卡片设计、运动曲线和音频处理,确保每个场景都呈现出经过精心导演的质感。它支持基于帧的工作流程,从配音测量、参数验证、场景生成、音符混音到最终质检,形成一个完整的自动化管道。该技能特别强调“逆向工程”能力——通过 `ffprobe` 和 `ffmpeg` 命令测量参考视频的色彩、节奏和布局,并将这些测量值转化为 `PARAMS.json` 中的参数。它最终的目标是让 AI 生成任何制片人或设计师都会认可的、可发布的短片,无论对话历史如何。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/uttamongithb/video-skill/tree/HEAD/skills/reel-from-script-v7

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

REEL-FROM-SCRIPT · v7 是做什么的?

一个根据你未编写的脚本、需要逆向分析的参考素材,以及一个毫无历史记忆的全新对话,制作一段 9:16 竖屏短片——它看起来经过精心导演,且绝不会出现制作事故。

v5 引入了布局并将设计硬编码到其中。v6 将所有数值移入了 PARAMS.json,并在渲染前放置了一个验证器。v7 是两个真实短片教会 v6 的成果——六色域循环、封面海报、每场卡片动画、连续场景跨度、自适应转场、音频陷阱,以及一个拒绝交付不良成片的单一 ./build.sh + scripts/qc.py。

承诺: 人类唯一编辑的文件是 PARAMS.json。唯一有权说 "不" 的是 prepare.py / qc.py。其他一切都是生成的,并且每个生成的内容都可以通过一个命令复现。


0 · 如果你是新手:前10分钟

export PATH=/home/user/node22/bin:$PATH        # Node >= 22
cd <project> && ./build.sh --from render        # 或从头开始遵循第3节

然后按此顺序阅读:第1节(外观如何构建)→ 第3节(管道)→ 第6节(设计手册)→ 第9节(故障目录)。不要自己发明布局:骨架就是设计。

永远不要做这四件事: 手动输入时长(测量配音)、将十六进制或像素值粘贴到合成中(修改 PARAMS.json)、手写 index.html(生成它)、或未经查看联系表就交付)。


1 · 为什么输出看起来是设计的(七条法则)

这些是该系列每个好镜头背后的实际决策。它们是规则,不是品味。

1. 一个固定到底部的锚定网格。 导语 → 主角 → 正文 → 芯片 → 主持人。下半部分从不移动:芯片始终处于同一纵坐标,主持人始终在相同位置被画框裁切。只有上半部分会重新构图。这就是为什么九个不同的场景读起来像一部电影。

2. 主角是一个词,不是一个句子。 1-3 个词,使用紧凑的显示字体,约占帧宽的 17-25%,行距紧密(0.88)。完整的句子放在芯片中(3-6 个词,供静音观看者阅读),细节放在卡片中。如果你不能用 3 个词说清楚,那么这个节拍就是两个节拍。

3. 每个节拍都使用不同的背景。 六个色域(奶油色 / 栗色 / 近黑色 / 鼠尾草色 / 海军蓝 / 薰衣草色)循环,确保没有两个相邻的节拍相同。颜色变化本身就是转场的另一半。prepare.py 如果发现两个连续场景共享一个色域,则会构建失败。

4. 证据,而非装饰。 卡片的存在是为了展示事物:文件列表、差异对比、浏览器、上传、仪表。如果一个节拍没有产物,则它是 type-led 类型,并且没有卡片。一张只有两行的卡片看起来有缺陷;四到六行看起来是刻意的(或者占卡片面积 ≥ 55% 的模拟图)。

5. 第一帧是海报。 场景 1 在 t=0 时构图(data-cover="1"):导语、主角、卡片和角色已经出现在屏幕上,芯片在 0.65 秒时着陆。一个以空白域开头就开始播放的短片会失去滚动观看的用户。

6. 动画仅限变换,并且尽早着陆。 入场动画持续 0.24-0.34 秒,使用 power2/3/4.out 缓出函数,并在节拍的前半部分完成。永远不要动画文本内容,永远不要对数字进行补间,永远不要让一个 1.5 秒的场景花费 0.6 秒进行转场。主角上的缓慢漂移使最后一秒保持活力。

7. 声音是标点,不是壁纸。 每秒 ≤ 1 个提示音:每次切换时一个弹跳音、UI 上的按键音、两个最大转折点上的渐强音、揭示时刻的钟琴音、行动号召上的通知/叮咚音。背景音乐音量设为 0.15,低于 −16 LUFS 的配音;母带 −14 LUFS / ≤ −1 dBTP。


2 · 契约:什么是固定的,什么是你的

不变量——经过验证,不可凭感觉编辑

不变量强制方式
每个文本/背景组合对可读WCAG ≥ 4.5:1,对 10 个渲染对和 6 个色域对
主角是主角,并且始终适应≥ 120 px,推导尺寸,必须适合 --hero-lines 在 --hero-band 内
主角位于导语下方,从不接触卡片推导的 band + --gap,硬性失败
正文在手机上可读≥ 24 px 且 ≥ bodyMin
无内容隐藏在平台 UI 下芯片底部 ≤ 安全区域底部,≥ 55% 可用区域
芯片永远不会与卡片碰撞cardTop + cardHmax ≤ chipTop
主持人始终被画框裁切,从不覆盖芯片presenterTop + h > 1.0,presenterTop ≥ chipBottom
两个连续场景永远不共享色域从每个合成中读取 data-field
第 0 帧是封面data-cover + 快照门控
每个场景使用不同姿势每个场景一个姿势文件,在审查时检查
交付物可播放且音量足够qc.py: 分辨率,fps,帧,LUFS,真峰值,静默空洞

变量——真正属于你的: 调色板值(6 个色域 + 4 个纸张色调,在对比度允许的前提下)· 格式(9:16, 4:5, 1:1, 720p)· 安全区域插入 · 在地板范围内的每个网格和比例 · 每场景原型 · 场景数量 · 词语 · 时长 · 姿势集 · 提示列表 · 磁盘上的字体。

如果你想要一个验证器无法检查的布局,你需要修改骨架并添加相应的检查。这就是自由的代价,也是输出不可能糟糕的原因。


3 · 管道(顺序不可协商)

#步骤命令为什么在这里
0逆向工程参考素材第4节你无法匹配一个你没有测量过的外观
1事实—迟到的声明会迫使重新录制
2脚本 → 章节assets/vo/sections.json每个节拍一个想法,1.2–9 秒
3先做配音python3 scripts/process_vo.pytimeline.json 是时钟;画面根据它剪裁
4外观PARAMS.json调色板,格式,网格,排版地板
5门控python3 scripts/prepare.py在对比度 / 排版 / 碰撞 / 色域节奏失败
6场景./scenes.sh每个节拍调用一次 new_scene.py,注入 token
7根python3 scripts/build_index.py连续跨度,自适应转场,无手写 index.html
8检查npx --yes [email protected] lint0 个错误是门控
9查看npx … snapshot --at "0,1.5,4,…"唯一能捕捉到“正确但丑陋”的步骤
10渲染npx … render --output renders/_raw.mp4对于 1080×1920 的 32 秒视频,软件 GL 约需 1 分 45 秒
11混音python3 scripts/mix_audio.py配音 + 背景音乐 + 提示音 → renders/master.wav (−14 LUFS)
12混流 + 交付build.sh 步骤 6–7mp4 + .srt + 缩略图,然后 qc.py

./build.sh 一步运行 3 到 12。./build.sh --from render 在配音已测量后跳过配音步骤。

步骤 3 详解——配音是时钟

# 每个章节一个片段,在 assets/vo/ 中命名为 vo1.mp3 … voN.mp3
python3 scripts/process_vo.py

它会修剪静音,仅当设置了 script_target 时才应用 atempo,将每个片段归一化到 −16 LUFS,然后写入 assets/vo/timeline.json:每个章节的 start/dur/end + root_duration。下游任何部分都不能知道此文件中不存在的时长。

使用天城体书写 say 中的印地语,用拉丁字母书写英语技术词汇(resume,job description,ATS score,DM)—— hi-IN 配音能正确识别韵律,同时仍能说出英语单词。caption 是 .srt 文件显示的内容。

步骤 7 详解——根是机械化的

build_index.py 按数字顺序查找 compositions/s*.html,读取测量的跨度,使它们连续(0 → 剪切 → 剪切 → … → 根,这样 VO 中 0.30 秒的间隙就不会产生黑场),在每次剪切前 0.36 秒触发一个转场,转场颜色为即将到来场景的色域,并让最后一个场景持续到音频的尾部。转场时间会缩短到一个短场景长度的 34-62% —— 一个 1.4 秒的场景无法容纳一个 0.62 秒的转场。

步骤 11 详解——两个音频陷阱

  • alimiter 默认情况下 level=true:它会自动将电平提升回上限,所以你的“限制器”变成了一个压缩器+增益补偿,混音会落在 −12.5 LUFS,而你的目标是 −14。始终设置 level=false。
  • 在单次线性通道中使用 loudnorm 会过冲。使用 ebur128 测量,精确移动 target − measured,然后限制。你可以验证的算术胜过一个会猜测的滤波器。

4 · 阶段 0——逆向工程参考视频

当需求是“观看这个并匹配它”时,测量它。十分钟,五个命令:

ffprobe -v error -show_entries format=duration:stream=width,height,r_frame_rate,codec_type -of default=nw=1 ref.mp4
ffmpeg -i ref.mp4 -vf "fps=1,scale=400:-1,tile=6x6" -frames:v 1 sheet.jpg      # 整部电影作为一张图像
python3 - <<'P'                                                                 # 每秒的色域调色板
from PIL import Image; import glob
for f in sorted(glob.glob("frames/f_*.jpg"))[::2]:
    im = Image.open(f).convert("RGB"); w,h = im.size
    print(f[-7:-4], im.getpixel((3,3)), im.getpixel((w-4,3)))
P
ffmpeg -i ref.mp4 -vn -ac 1 -ar 16000 -c:a pcm_s16le audio.wav                  # 用于脚本

从中读取出:时长和剪辑节奏(每个节拍多长)、色域调色板(采样角落,而非中间)、排版行为(紧凑大写?逐词构建?高亮框?)、布局(角色在哪里,文本块在哪里)、UI 产物(哪些模拟图)、声音(提示音密度)。这六个数字就是整个艺术指导。

如果需求提供了参考素材但没有脚本,那么参考素材就是脚本:转录音频(faster-whisper,int8,base 模型 → 对于 32 秒的印地英语约需 7 秒)并从帧中读取屏幕上的文案。不要重写文案——一个系列有自己的声音。

翻译,不要复制。 这里的参考素材是 1280×720;交付物是 1080×1920。相同的调色板,相同的排版,相同的模拟图——但主角区域、芯片锚点和主持人裁切是作为比例重新推导的。在 9:16 格式中,参考素材的 8-10 个词块会低于 24 像素的正文地板,因此文案被不同地拆分:主角 1-3 个词,芯片一句,卡片细节。


5 · 文件

PARAMS.json                     唯一的设计文件
tokens.css                      生成的收据(勿编辑)
index.html                      由 build_index.py 生成(勿编辑)
SKILL.md · COMPONENTS.md · README.md
build.sh                        整个管道
scenes.sh                       每个场景,可复现
components/                      7 个卡片主体,可使用 --card-body @… 传递
compositions/
  _scene-base.html.tmpl          核心骨架——零字面十六进制,零字面像素
  wipe.html                     唯一的转场
  sN-*.html                     由 new_scene.py 生成
  _examples/                    三个已实现场景(未挂载:build_index 只读取 compositions/s*.html)
scripts/
  process_vo.py                 配音 → timeline.json
  prepare.py                    门控:地板 + token 注入
  new_scene.py                  基础模板 → 正确的场景
  build_index.py                时间线 + 场景 → 根
  mix_audio.py                  配音 + 背景音乐 + 提示音 → master.wav
  make_deliverables.py          .srt + 缩略图
  qc.py                         一个命令,PASS/FAIL 基于 10 个门控
  cutout.py · gen_sfx.py        素材
assets/{fonts,presenter,vo,sfx,music}/

6 · 设计手册(实际该选什么)

节拍 → 原型。 证据 → card-led。一个数字 → stat-led(里程表,--digits)。陈述句、过渡、品牌卡片 → type-led。开场钩子和行动号召几乎总是 card-led,因为两者都需要一个产物(证明问题的文件列表;证明行动号召的评论线程)。

节拍 → 色域。 冷暖交替,从不重复。一个实用的六色域循环:accent → ground → ink → secondary → tertiary → quaternary。深色域(ink,tertiary)会使主持人消失,因此那里的光晕设为 0.20 → 0.42(骨架从 data-field 执行此操作);在工具揭示和“AI 完成了工作”的节拍中使用它们,戏剧性有助于效果。

节拍 → 姿势。 相同角色,相同服装,每个场景一个姿势,与台词的 emotional 匹配:耸肩(疑问)· 扶额(问题)· 呈现(提议)· 托腮(好奇)· 回忆(回想)· 竖拇指(胜利)· 指(步骤)· 灵光一现(啊哈)· CTA(请求)。从基础图像生成缺失的姿势,并使用 cutout.py 进行遮罩;保持白色背景规则和大腿中部裁切,以便干净地抠像。

屏幕上的文字。 主角:情绪化的动词或数字(SAME RESUME?,CUSTOMIZE KARO,TAILOR,ATS SCORE)。芯片:静音观看者需要的句子(har company mein bhej rahe ho?)。卡片标题:产物的名称(applied / 12 companies)。卡片元数据:一个微小的事实(this week,matched 3 of 7)。

当一个节拍太短无法设计时(1-2 秒)。 保留场景,去掉第二层:主角 + 芯片 + 主持人,type-led,一次揭示。不要将一张卡片和一个交错列表塞进 1.4 秒——它看起来像故障。

当一个节拍很长时(8-9 秒,通常是 CTA)。 间隔 1.8-2 秒安排三次揭示(评论 → DM → 链接),让缓慢漂移拖出尾巴。一个 8 秒的静态帧是“看起来廉价”的最常见原因。

转场。 一个转场,持续 0.34-0.62 秒,颜色 = 即将到来场景的色域,方向交替。没有其他转场类型:一致性使八个切换感觉像是有作者创作的。

最后一秒。 最后一帧必须是一个经过设计的帧,包含手柄和网站——在那里暂停的观看者应该能够采取行动。


7 · 音频手册

时刻提示音增益
每次剪切pop0.50
两个最大的转折riser 在剪切前 0.3 秒0.28–0.30
UI 元素着陆click,key0.38–0.45
列表逐个出现key ×N,间隔 0.12 秒0.40
揭示 / 分数chime0.36–0.42
CTAnotify,然后 1.7 秒后 ping0.32–0.40
错误 / 拒绝error(谨慎使用——它只作为喜剧元素阅读一次)0.30

提示音偏移量是相对于章节的,在 assets/sfx/cues.json 中("vo7+1.68"),因此重新录制的配音不会使设计失效。永远不要让提示音落在单词的第一个音节上;一个按键音属于该音节开始后的 20-60 毫秒处。

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

相关技能