mcpField
V
vid-sizzle-reel

vid-sizzle-reel

github.com/varnan-tech创意与媒体68745 次安装2 周前更新
代码仓库

关于 vid-sizzle-reel

vid-sizzle-reel 是一项根据品牌素材和关键信息制作高节奏宣传短片的技能,适用于需要展示品牌信息或营造活动氛围的团队。它采用快速剪辑和音乐优先的结构,不围绕单一叙事展开。

主要功能

  1. 01根据 3–5 条信息制作短片
  2. 02支持四种基调
  3. 03支持快速、电影式或混合剪辑
  4. 04配置品牌素材、配乐和片尾
  5. 05使用 HyperFrames、GSAP 与 FFmpeg 渲染

适用场景

  1. 01制作社交媒体宣传视频
  2. 02为产品发布或活动制作氛围短片
  3. 03将品牌信息与行动号召编排进片尾

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/varnan-tech/opendirectory --skill vid-sizzle-reel

安装后在 Claude Code 中输入/vid-sizzle-reel确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
references/
cut-patterns.md
tone-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 营造能量与兴奋感——快速剪辑、音乐优先、不围绕单一故事节点展开

关键规则(每次生成前阅读)

  1. 自己撰写核心信息——或请用户撰写。 这些是会出现在屏幕上的确切短句。“AI will figure it out”只会生成填充内容。3-5 条有力短句就是精彩集锦的全部内容。

  2. 品牌名称只能出现在 Land 部分。 Cold Open 和 Build 营造紧张感,但不提品牌名称。Land 部分负责揭晓。

  3. 编写任何 HTML 之前,先在脚本顶部的注释中声明节奏模式。 格式:// RHYTHM: flash-sequence | Cold[0-5s]: stat | Build[5-40s]: msg(1.5s)|flash|... | Peak[40-55s]: ... | Land[55-60s]: logo+CTA。每项时间安排都要依据此模式检查。

  4. 先在 CSS 中构建最终布局——暂不使用 GSAP。 在静态 CSS 中将每个元素放在最醒目的位置,然后使用 gsap.from() 添加入场动画,并使用 gsap.to() 添加退场动画。不要将元素定位在动画的起始状态。

  5. 每个定时元素都必须有 class="clip"。 HyperFrames 必需。缺少此属性时,播放器无法识别该元素。

  6. 每个片段都必须有 data-start、data-duration、data-track-index。 不例外。同一轨道上的片段不能重叠——请使用不同的轨道索引。

  7. 不要使用 Math.random()。 HyperFrames 要求合成结果具有确定性。任何伪随机值都应使用带种子的 PRNG(mulberry32)。

  8. 所有 GSAP 时间线都必须以 { paused: true } 启动,并注册到 window.__timelines["comp-id"]。 HyperFrames 播放器负责控制播放——绝不要调用 tl.play()。

  9. 绝不要在 .scene-content 容器上使用 position: absolute。 使用 width:100%; height:100%; padding:Npx; display:flex。position:absolute 仅用于装饰元素。

  10. 音乐使用带有 data-track-index 的独立 <audio> 元素。 视频必须设置 muted playsinline。不要将音频放入 <video> 元素。

  11. 生成任何 HTML 之前,请阅读 references/cut-patterns.md 和 references/tone-presets.md。

  12. 绝不要在聊天中输出 HTML。 保存到文件,只显示摘要。


第 1 步:收集信息

必填:

  • key_messages — 3-5 条要闪现在屏幕上的有力短句(必须由用户撰写)

可选参数及默认值:

参数默认值说明
brand_assets无Logo URL/路径、品牌颜色(十六进制)、关键截图
toneenergeticenergetic / cinematic / emotional / professional
music无文件路径或 BPM/流派字符串(例如 "128bpm electronic")
duration6030 / 60 / 90 秒
aspect_ratio9:169:16 (1080x1920) / 16:9 (1920x1080)
cut_styleautofast(1-2 秒)/ cinematic(3-5 秒)——auto 会根据 tone 推导
end_cardautoLand 部分显示 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 推导切点时间:

Section30s60s90s
冷开场0-5s0-5s0-8s
铺垫5-25s5-40s8-65s
高潮25-28s40-55s65-80s
收尾28-30s55-60s80-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 气流声)700msBuild → Peak 转场处
cta-chimeA 大调和弦(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

评论

支持 Markdown