关于 vid-sizzle-reel
vid-sizzle-reel 是一项根据品牌素材和关键信息制作高节奏宣传短片的技能,适用于需要展示品牌信息或营造活动氛围的团队。它采用快速剪辑和音乐优先的结构,不围绕单一叙事展开。
主要功能
- 01根据 3–5 条信息制作短片
- 02支持四种基调
- 03支持快速、电影式或混合剪辑
- 04配置品牌素材、配乐和片尾
- 05使用 HyperFrames、GSAP 与 FFmpeg 渲染
适用场景
- 01制作社交媒体宣传视频
- 02为产品发布或活动制作氛围短片
- 03将品牌信息与行动号召编排进片尾
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ varnan-tech/ opendirectory --skill vid-sizzle-reel安装后在 Claude Code 中输入/vid-sizzle-reel确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdreferences/cut-patterns.mdtone-presets.md详细介绍
vid-sizzle-reel
根据品牌素材和核心信息,生成高能量的精彩集锦或宣传视频。 流程:HyperFrames HTML 合成(GSAP 时间线)→ 无头 Chromium → FFmpeg H.264 MP4。 不使用 Runway。不使用 Pika。不使用 AI 视频 API。除 Node.js 和 FFmpeg 外,零运行成本。
与 vid-product-launch 的区别:
vid-product-launch讲述叙事故事——一个铺垫充分的揭晓、五个部分、张力弧线vid-sizzle-reel营造能量与兴奋感——快速剪辑、音乐优先、不围绕单一故事节点展开
关键规则(每次生成前阅读)
-
自己撰写核心信息——或请用户撰写。 这些是会出现在屏幕上的确切短句。“AI will figure it out”只会生成填充内容。3-5 条有力短句就是精彩集锦的全部内容。
-
品牌名称只能出现在 Land 部分。 Cold Open 和 Build 营造紧张感,但不提品牌名称。Land 部分负责揭晓。
-
编写任何 HTML 之前,先在脚本顶部的注释中声明节奏模式。 格式:
// RHYTHM: flash-sequence | Cold[0-5s]: stat | Build[5-40s]: msg(1.5s)|flash|... | Peak[40-55s]: ... | Land[55-60s]: logo+CTA。每项时间安排都要依据此模式检查。 -
先在 CSS 中构建最终布局——暂不使用 GSAP。 在静态 CSS 中将每个元素放在最醒目的位置,然后使用
gsap.from()添加入场动画,并使用gsap.to()添加退场动画。不要将元素定位在动画的起始状态。 -
每个定时元素都必须有
class="clip"。 HyperFrames 必需。缺少此属性时,播放器无法识别该元素。 -
每个片段都必须有
data-start、data-duration、data-track-index。 不例外。同一轨道上的片段不能重叠——请使用不同的轨道索引。 -
不要使用
Math.random()。 HyperFrames 要求合成结果具有确定性。任何伪随机值都应使用带种子的 PRNG(mulberry32)。 -
所有 GSAP 时间线都必须以
{ paused: true }启动,并注册到window.__timelines["comp-id"]。 HyperFrames 播放器负责控制播放——绝不要调用tl.play()。 -
绝不要在
.scene-content容器上使用position: absolute。 使用width:100%; height:100%; padding:Npx; display:flex。position:absolute仅用于装饰元素。 -
音乐使用带有
data-track-index的独立<audio>元素。 视频必须设置muted playsinline。不要将音频放入<video>元素。 -
生成任何 HTML 之前,请阅读
references/cut-patterns.md和references/tone-presets.md。 -
绝不要在聊天中输出 HTML。 保存到文件,只显示摘要。
第 1 步:收集信息
必填:
key_messages— 3-5 条要闪现在屏幕上的有力短句(必须由用户撰写)
可选参数及默认值:
| 参数 | 默认值 | 说明 |
|---|---|---|
| brand_assets | 无 | Logo URL/路径、品牌颜色(十六进制)、关键截图 |
| tone | energetic | energetic / cinematic / emotional / professional |
| music | 无 | 文件路径或 BPM/流派字符串(例如 "128bpm electronic") |
| duration | 60 | 30 / 60 / 90 秒 |
| aspect_ratio | 9:16 | 9:16 (1080x1920) / 16:9 (1920x1080) |
| cut_style | auto | fast(1-2 秒)/ cinematic(3-5 秒)——auto 会根据 tone 推导 |
| end_card | auto | Land 部分显示 Logo + 标语 + CTA URL |
cut_style 的自动默认值:energetic → fast;professional → fast(2 秒);cinematic → cinematic;emotional → mixed
如果缺少 key_messages,请原样询问:
"要生成精彩集锦,我需要你的核心信息——也就是会闪现在屏幕上的确切短句。请给我 3-5 条有力短句。这是你为这段视频撰写的最重要内容。
示例:'Used by 500+ growth teams' / 'From days to minutes' / 'Works with Claude, Codex, Gemini'
也可以提供:基调(energetic/cinematic/emotional/professional)、时长(30/60/90s)、品牌颜色或 Logo URL。"
如果已提供 key_messages → 立即继续第 2 步。
第 2 步:安装 HyperFrames
安装 HyperFrames skills(仅首次需要安装 — 如果已安装则跳过):
npx skills add heygen-com/hyperframes
验证环境:
node --version # must be >= 22
ffmpeg -version # must be present
搭建项目脚手架:
npx hyperframes init sizzle-[slug] --example kinetic-type --non-interactive
cd sizzle-[slug]
Slug:根据 end_card 品牌名称或第一个 key_message 使用 kebab-case,最多 25 个字符。
第 3 步:内部架构(绝不向用户展示)
1. 根据 duration + cut_style 推导切点时间:
| Section | 30s | 60s | 90s |
|---|---|---|---|
| 冷开场 | 0-5s | 0-5s | 0-8s |
| 铺垫 | 5-25s | 5-40s | 8-65s |
| 高潮 | 25-28s | 40-55s | 65-80s |
| 收尾 | 28-30s | 55-60s | 80-90s |
将每个边界转换为毫秒。根据 cut_style 计算每个场景的时长:
fast:每条消息 1.2s-1.8s(默认使用 1.5s)cinematic:每条消息 3.5s-5.0s(默认使用 4.0s)mixed:每条消息 2.0s-4.0s,根据各部分的能量变化调整
2. 将 key_messages 映射到场景:
- 冷开场(1 个场景):一个令人震撼的数据或问题 — 不得出现品牌名称,营造悬念
- 铺垫:每条 key_message 对应一个场景
- 高潮:以双倍大小重复最有力的信息,或快速闪现组合 2 条信息
- 收尾:品牌名称 + 标语 + CTA URL
3. 如果提供了音乐,则检测节拍同步:
npx hyperframes tts --analyze-beats [music-file]
如果无法检测,则根据 BPM 计算:beat_ms = 60000 / BPM。每隔 2 拍对齐一次切点。
4. 选择语调预设 — 阅读 references/tone-presets.md 获取 CSS tokens。
5. 声明节奏模式 — 在脚本顶部添加注释:
// RHYTHM: flash-sequence
// Cold Open [0-5000ms]: stat
// Build [5000-40000ms]: msg-1(1500ms)|flash|msg-2(1500ms)|flash|msg-3(1500ms)|flash|msg-4(1500ms)|flash|build-accum(10000ms)
// Peak [40000-55000ms]: msg-strongest(1200ms)|flash|msg-2nd(1200ms)|flash|HOLD(5600ms)
// Land [55000-60000ms]: logo+tagline+cta
6. 确定像素尺寸:
9:16→ W=1080,H=1920(默认 — Instagram Reels、TikTok、YouTube Shorts)16:9→ W=1920,H=1080
第 4 步:HyperFrames HTML 合成
编写代码前,阅读 references/cut-patterns.md 和 HyperFrames skill(/hyperframes)。
必需的 HTML 骨架:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
[font CDN link from tone preset]
<style>
:root {
[all CSS tokens from tone preset]
}
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
</style>
</head>
<body>
<div
data-composition-id="sizzle-[slug]"
data-width="[W]"
data-height="[H]"
style="position:relative;width:[W]px;height:[H]px;overflow:hidden;background:var(--bg)"
>
[if cut-flash: true]
<div id="cut-flash"
style="position:absolute;inset:0;background:var(--cut-flash-bg);opacity:0;pointer-events:none;z-index:200"></div>
[end if]
[if film-grain: true]
<canvas id="grain-overlay"
width="240" height="135"
style="position:absolute;inset:0;width:[W]px;height:[H]px;pointer-events:none;opacity:0.022;mix-blend-mode:overlay;z-index:50"></canvas>
[end if]
[if vignette: true]
<div id="vignette-overlay"
style="position:absolute;inset:0;background:radial-gradient(ellipse at center,transparent 35%,rgba(0,0,0,0.65) 100%);pointer-events:none;z-index:51"></div>
[end if]
<div id="scene-cold"
class="clip"
data-start="0"
data-duration="5"
data-track-index="0"
style="position:absolute;inset:0;opacity:0"
>
<div class="scene-content" style="width:100%;height:100%;padding:120px;display:flex;flex-direction:column;align-items:center;justify-content:center;box-sizing:border-box">
[cold open content — one stat or impact phrase, no brand name]
</div>
</div>
[one div per Build scene, data-start increments by cut duration]
[Peak scene(s)]
[Land scene — brand name + tagline + CTA]
[if music provided]
<audio id="music"
class="clip"
data-start="0"
data-duration="[total_duration]"
data-track-index="10"
data-volume="0.85"
src="[music_path]"
></audio>
[end if]
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/gsap.min.js"></script>
<script>
// ── RHYTHM DECLARATION ──────────────────────────────────────────────────────
// RHYTHM: [flash-sequence | cinematic-hold | beat-sync | mixed]
// Cold Open [0-Nms]: ...
// Build [N-Nms]: ...
// Peak [N-Nms]: ...
// Land [N-Nms]: ...
// ── SEEDED PRNG (for grain only — no other random values) ───────────────────
function mulberry32(seed) {
return function() {
seed |= 0; seed = seed + 0x6D2B79F5 | 0;
let t = Math.imul(seed ^ seed >>> 15, 1 | seed);
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
return ((t ^ t >>> 14) >>> 0) / 4294967296;
};
}
[if film-grain: true]
// ── FILM GRAIN (cinematic/emotional only) ───────────────────────────────────
const grainCanvas = document.getElementById('grain-overlay');
const grainCtx = grainCanvas ? grainCanvas.getContext('2d') : null;
// Grain updated by GSAP ticker (not per-frame capture — HyperFrames handles this)
[end if]
// ── GSAP TIMELINE ───────────────────────────────────────────────────────────
const tl = gsap.timeline({ paused: true });
// ── COLD OPEN ───────────────────────────────────────────────────────────────
[cold open entrance and exit tweens — see cut-patterns.md for exact pattern]
// ── BUILD SECTION ───────────────────────────────────────────────────────────
[per-message tweens — flash-sequence or cinematic-hold from cut-patterns.md]
// ── PEAK SECTION ─────────────────────────────────────────────────────────────
[peak tweens — same pattern as build but tighter timing]
// ── LAND SECTION ─────────────────────────────────────────────────────────────
[land entrances — logo, tagline, CTA. No exit — holds to end]
// ── TIMELINE REGISTRATION ────────────────────────────────────────────────────
window.__timelines = window.__timelines || {};
window.__timelines["sizzle-[slug]"] = tl;
</script>
</div>
</body>
</html>
设计质量规则:
- 冷开场数据:16:9 使用 ≥160px 字号,9:16 使用 ≥100px 字号
- 关键信息:使用 ≥80px 字号 — 确保一眼可读
- 收尾部分的品牌名称:16:9 使用 ≥120px 字号
- 所有颜色均来自预设 token 变量 — 除了 canvas
fillStyle中的字面量十六进制颜色var(--accent)外,不得使用其他自由十六进制颜色 scene-content始终使用padding + flex— 内容容器上不得使用position:absolute- 每个带有
data-start的元素都必须添加class="clip"
第 5 步:自检 QA(第 6 步前修复所有问题)
内容:
-
key_messages— 每个短语恰好出现一次,不得重复 - 品牌名称只能出现在收尾部分(不能出现在冷开场、铺垫或高潮中)
- 冷开场不得包含品牌名称或产品名称 — 只能包含数据或有冲击力的短语
- 收尾部分至少包含:品牌名称 + 标语 + CTA URL(三个元素)
- 最后一帧中包含 end_card CTA URL
HyperFrames 合约:
- 每个带有
data-start的元素都添加了class="clip" - 每个 clip 都包含
data-start、data-duration、data-track-index - 根 composition div 包含
data-composition-id - 已注册
window.__timelines["sizzle-[slug]"] = tl - 所有时间线都以
{ paused: true }启动 - 不使用
Math.random()— 仅使用带种子的 PRNG - 不调用
tl.play()或tl.resume()
GSAP / 布局:
- 所有入场都使用
gsap.from()(从屏幕外进入 CSS 位置) - 所有退场都使用
gsap.to()(从 CSS 位置移至屏幕外) -
.scene-content容器上不得使用position:absolute - 在脚本顶部的注释中声明节奏模式
切点时间:
-
fast语调:平均切点时长 ≤ 2.0s -
cinematic语调:平均切点时长 ≥ 3.0s -
energetic语调下,每个切点边界都会触发闪光效果(60ms,透明度 0→1→0) - 同一轨道上的 clip 不得重叠(检查所有
data-track-index分组)
SFX:
- 存在
window.__sfxTimeline,且位置在时间线注册之前 - 每条关键信息都有一个
word-hit事件 - 在铺垫 → 高潮的过渡边界触发
whoosh - 在收尾开始时触发
cta-chime - 不得在 500ms 之前触发 SFX
第 6 步:Lint、渲染、输出
npx hyperframes lint
npx hyperframes inspect --json
修复所有 lint 错误。修复所有 inspect 错误(文本溢出、clip 伸出容器)。然后进行渲染:
npx hyperframes render --output sizzle/[slug]/sizzle-reel.mp4
输出:
## Sizzle Reel: [brand name from end_card]
Tone: [tone] | Duration: [N]s | Cut style: [cut_style] | Aspect: [ratio]
Rhythm: [declared pattern]
Sections
Cold Open [0-Ns]: [impact stat or phrase]
Build [N-Ns]: [N key messages listed]
Peak [N-Ns]: [strongest message at max scale]
Land [N-Ns]: [brand name] + "[tagline]" + [CTA URL]
Files
Source: sizzle/[slug]/index.html
Output: sizzle/[slug]/sizzle-reel.mp4
SFX 时间线(嵌入每个合成项目中)
与 vid-product-launch 使用相同的 FFmpeg 合成 SFX 系统。将 window.__sfxTimeline 放在 GSAP 时间线注册之前。
SFX 类型参考(用于精彩片段集锦):
| 类型 | 声音 | 时长 | 放置位置 |
|---|---|---|---|
word-hit | 低频重击(50Hz)+ 瞬态点击声(2.2kHz)+ 噪声爆发 | 180ms | 每个 key_message 场景开头各一次 |
whoosh | 双频段噪声扫频(1.1kHz 主体 + 4-8kHz 气流声) | 700ms | Build → Peak 转场处 |
cta-chime | A 大调和弦(440+554+659+880Hz)+ 带 aecho 的铃声余韵 | 1.2s | 正好位于 Land 开始处 |
window.__sfxTimeline = [
// one word-hit per key_message (computed from scene start times)
{ ms: MSG_1_START_MS, sfx: 'word-hit', vol: 0.50 },
{ ms: MSG_2_START_MS, sfx: 'word-hit', vol: 0.50 },
{ ms: MSG_3_START_MS, sfx: 'word-hit', vol: 0.50 },
// ... repeat for each message
{ ms: PEAK_START_MS - 700, sfx: 'whoosh', vol: 0.55 },
{ ms: LAND_START_MS, sfx: 'cta-chime', vol: 0.65 },
];
根据声明的分段时间常量计算所有 ms 值。绝不要硬编码。
提示建议(用户寻求指导时显示)
“自己撰写关键信息。它们是这段视频的全部内容。3 条犀利的文案胜过 10 条含糊的文案。”
“先选音乐,再选画面。BPM 决定剪辑风格,剪辑风格决定每一项时间安排。”
“冷开场:一个数字。不是句子,不是标语,而是一个具体、出人意料的数字。它能赢得 5 秒的关注。”
“Land 部分不是片尾页。Logo + 一句话 + 一个 URL。更多内容只会削弱 CTA。”
“让基调契合渠道。社交媒体和 Product Hunt 适合活力十足的风格。B2C 高端产品和投资者演示适合电影感风格。企业会议适合专业风格。众筹适合情感化风格。”
好的:
Sizzle reel, 60 seconds. Tone: energetic. Key messages: ['AI skills, ready to install' /
'52+ skills across GTM, content, research' / 'Works with Claude, Codex, Gemini' /
'Zero setup. Instant value.']. Music: 128bpm electronic. Cut style: fast.
End card: OpenDirectory + 'AI skills, ready to install' + 'opendirectory.dev'. Aspect: 9:16.
不好的:
hype video for our company