Communitygithub.com

KoeYe/awsome-demovideo-skill

专为Remotion 4.x设计的宣传/演示/预告片视频构建工作流。封装了项目布局、动画原语、渲染命令以及实际工程中需要重新发现的常见陷阱。

awsome-demovideo-skill 是什么?

这是一个为Remotion 4.x设计的视频创作AI技能,专用于构建宣传片、演示视频和预告片。其核心理念是将视频分解为多个可独立渲染的场景,每个场景以独立的MP4文件输出,最终在DaVinci Resolve、Premiere或Final Cut Pro等下游编辑器中组装,并添加音乐、配音和转场效果。这种“每个场景单独渲染,编辑器组装”的工作流避免了在Remotion中处理所有时序、音频和特效的繁琐与低效。技能特别适合处理论文、项目规范或现有仓库的输入,它通过分析源材料提取叙事节拍,自动生成带占位符的场景代码和一份ASSETS.md清单,明确告知用户需要录制哪些片段。用户录制完成后,只需将片段放入指定目录,技能便会自动替换占位符,完成视频的最终渲染。该技能适用于Claude Code、Cline、Cursor和Aider等主流平台,提供了一套从源材料到成品视频的完整、高效解决方案。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add KoeYe/awsome-demovideo-skill

在你喜欢的 AI 中提问

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

文档

remotion-demo-video

一个精简的工作流,用于构建Remotion 4.x的宣传/演示/预告片视频。它编码了项目布局、动画原语、渲染命令以及实际中会浪费大量时间的特定陷阱。

何时使用此技能

当用户想要创建、编辑、渲染或调试Remotion视频时触发。特别是:

  • 为产品/论文/仓库演示搭建一个新的Remotion项目
  • 向现有Remotion项目添加新场景
  • 将预先录制的屏幕录制片段拼接成一个包含叠加层、标题和转场的精美视频
  • 渲染——单个场景、完整时间线、透明(alpha)叠加层、PNG序列
  • 调试Remotion特有的怪异问题(composition-id不匹配、默认值不同步、useCurrentFrame在<Sequence>内返回意外值、Windows上ffmpeg清理时的EPERM错误等)

如何理解工作流

一个精美的Remotion视频不是“一个你可以渲染成单个MP4的巨大时间线”。它是一组小型、可单独渲染的场景——每个场景渲染为自己的片段,并在下游编辑器(DaVinci Resolve、Premiere、Final Cut)中组装,在其中添加音乐、旁白和场景间转场。

这是从SimWorld宣传片发布中得出的最大见解,此技能应默认引导用户采用此工作流。试图在Remotion中完成所有事情——最终的时序调整、音频混合、淡入淡出——既痛苦又缓慢;而在编辑器中做这些则轻而易举。

让每个工具发挥其优势

  • Remotion擅长的: 可编程的、可重复的、参数化的场景——动画标题、数据驱动图表、UI模型、任何你会在After Effects中手工设置关键帧的内容。场景逻辑存在于代码中;“用30个不同的产品名称重建同一个标题”只是一个属性更改。
  • 下游编辑器擅长的: 时序、音频、淡入淡出、调色、“让这个场景延长1.2秒”。所有这些在编辑器中是立竿见影的,而在Remotion中则需要编辑代码并重新渲染。

工作循环

  1. 确定脚本。 逐节提纲,每节有目标秒数。总时长通常为30-90秒。
  2. 设置一次项目外壳。 theme.ts(调色板、字体、fps、尺寸)、Root.tsx(合成注册表)、共享组件(Reveal、ProgressBar、缓动函数)。
  3. 一次构建一个场景。 每个场景是一个自包含的<AbsoluteFill> React组件,针对frame 0设计,并有自己独立的<Composition>,以便你可以单独渲染它。在Studio中迭代(npm run dev),使用属性面板;喜欢后渲染为MP4(npm run render:<scene>)。
  4. 将每个完成的场景渲染为自己的片段——这是实际的交付物,而不是完整时间线的MP4。每个场景的片段可以拖放到任何编辑器的时间线中。对于需要alpha通道的片段(下三分之一、要合成到屏幕录制上的标志),使用--codec=prores --pixel-format=yuva444p10le --prores-profile=4444。
  5. (可选)将场景连接到Main.tsx中,使用从theme.ts中的TIMELINE常量读取的<Sequence>块。这为你提供了一个完整时间线预览渲染(npm run render),用于进行完整性检查——但将其视为预览,而非主版本。
  6. 在DaVinci / Premiere / Final Cut中组装。 将每个场景的片段按顺序拖到轨道上,调整修剪手柄以获得精确时序,添加音乐/旁白/音效设计,在场景之间应用转场(对于这种审美,1帧的淡入淡出通常感觉合适),调色,导出。

何时建议完整的Remotion渲染

只有在以下情况下,完整时间线渲染才是正确的输出:

  • 用户没有下游编辑器,今天需要一个可交付文件。
  • 视频完全静音(完全没有音乐或旁白)。
  • 没有比硬切更复杂的场景间转场(即使如此,使用逐个场景的方法在代码中调整也更容易)。

否则,默认建议逐个场景渲染 + 编辑器组装。

此技能在scaffold/中附带了一个工作脚手架——将其复制为新项目的起点,然后根据需要阅读下面的参考资料。

实际的端到端循环(当输入是论文/规范/仓库时)

这是此技能真正设计用于的工作流。用户通常不会过来说“我想要一个显示X的动画标题”。他们会带着一个论文PDF、项目规范或现有仓库,问题是“把这个变成一段60秒的视频”。此技能的存在就是为了使这个循环快速且易于处理。

1. 源材料        →  论文 PDF / 规范 / 现有仓库 / README
        ↓
2. Claude分析    →  提取叙事节拍;确定每个节拍需要展示什么
                      (UI界面、实验录制、图表、智能体视角等)
        ↓
3. Claude搭脚手   →  场景代码 + 每个视觉区域中的<VideoPlaceholder slot="..." />
   架,带占位符       再加上一个ASSETS.md,列出用户需要录制的所有片段
                      (插槽名称、时长、应显示的内容)
        ↓
4. 用户录制素材   →  将mp4文件放入public/clips/<slot>.mp4
                      匹配脚手架中的插槽名称
        ↓
5. Claude替换     →  将<VideoPlaceholder>替换为
   占位符为片段        <OffthreadVideo src={staticFile("clips/<slot>.mp4")}>
        ↓
6. 逐个场景迭代   →  npm run render:<scene>,观看,调整文本/
                      时序/动画,重新渲染。代码端的更改很快;
                      如果需要重新录制素材,那是循环中最慢的部分。
        ↓
7. 在编辑器中组装 →  将每个场景的MP4放入DaVinci / Premiere / FCP,
                      添加音乐 + 旁白 + 场景间转场,导出。

第2步详解——分析源材料

当用户提供论文/规范时,在编写任何代码之前执行此操作:

  1. 提取叙事。 3-5个节拍的弧线是什么?(“问题 → 我们的方法 → 关键结果 → 影响”是一个起始模板;根据实际论文进行调整。)叙事驱动场景列表。
  2. 对于每个节拍,决定展示什么。 仅动画文字很无聊。每个节拍都应该有一个具体的视觉内容——一个UI界面、一个实验录制、一个图表、一个比较、一个系统图。将视觉效果与声称相匹配:如果论文声称“方法X快3倍”,显示并排的计时。
  3. 区分Remotion生成的内容和用户必须录制的内容。 Remotion擅长:标题、转场、图表、UI模型、布局、动画图表。Remotion无法生成:用户产品的真实屏幕录制、实验素材、智能体视角、项目外部的任何内容。将这些列为用户提供的素材。
  4. 在搭建脚手架之前草拟时间线。 逐节节拍,目标时长总和为30-90秒。相应地更新theme.ts中的TIMELINE。总长度应在构建场景之前确定,以便每个场景都知道自己的预算。

第3步详解——使用占位符搭建脚手架

此技能的关键交接约定:插槽名称。用户需要录制的每个片段都有一个稳定的slot字符串。占位符和真实片段共享该插槽名称。

// 搭建脚手架期间:
<VideoPlaceholder
  slot="agent-loop"
  description="连续智能体录制:行走、失败、使用更新策略重试。"
  accent={COLORS.blue}
/>

// 用户录制public/clips/agent-loop.mp4后,替换为:
<OffthreadVideo
  src={staticFile("clips/agent-loop.mp4")}
  muted
  style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }}
/>

始终在脚手架根目录中编写一个ASSETS.md(脚手架附带一个模板)。它列出用户需要填写的每个插槽,包括:插槽名称(=文件名)、应显示的内容、目标时长、宽高比建议以及任何时序说明(例如“失败事件大约在7秒标记处”)。这是用户录制任务的单一事实来源。

第4-5步详解——资产交接

用户带着放入public/clips/的文件回来。需要检查三件事:

  1. 文件名与插槽名称完全匹配。 agent-loop.mp4,而不是agent_loop.mp4或AgentLoop.mp4。
  2. 时长至少为场景长度(如果片段较短且需要重复,则使用<Loop>)。
  3. 宽高比合理——对于全屏场景,匹配合成的1920×1080。对于2×2网格中的卡片,4:3或16:9都适用;只需保持一致。

然后机械地将每个<VideoPlaceholder>替换为<OffthreadVideo>。每个插槽只需一行替换;无需更改动画逻辑。如果用户的录制是时序敏感的(例如,“失败事件在7秒处”),则将其作为场景属性暴露出来,以便依赖时序的叠加层(FAIL印章、奖励数字)可以在无需重新录制的情况下进行调整。

为什么这个循环对技能很重要

此技能的工作不是“按需编写Remotion代码”——而是使从源材料到发布视频的循环易于处理。占位符模式正是让Claude能够一次性搭建整个视频的结构,然后返回一个ASSETS.md,以便用户确切知道要录制什么的关键。没有它,循环就会停滞——用户录制错误的内容,或者脚手架等待素材,或者代码结构必须在事后进行改造。

当用户带着源材料出现时,正确的开场白通常是:

“让我先阅读论文/规范。然后我将提出一个包含目标时长的逐节大纲、一个你需要录制的片段列表,并使用占位符搭建代码脚手架,这样你可以在我继续构建场景的同时开始录制。”

新项目快速入门

# 1. 复制脚手架
cp -r <skill-dir>/scaffold ./my-demo
cd my-demo
npm install

# 2. 打开Remotion Studio进行实时编辑
npm run dev    # 打开 http://localhost:3000

# 3. 迭代时渲染单个场景
npm run render:opening

# 4. 准备就绪后渲染完整时间线
npm run render

脚手架包含一个工作场景(OpeningTitle)、奶油色温暖主题、Reveal + 缓动函数、ProgressBar、一个占位符Main时间线以及一个预配置了渲染脚本的package.json。

项目布局(行之有效的结构)

my-demo/
├── package.json                      # 渲染脚本、预渲染钩子
├── remotion.config.ts                # 编解码器/像素格式默认值
├── tsconfig.json
├── public/
│   ├── assets/                       # 标志、静态图像(staticFile("assets/..."))
│   └── clips/                        # 屏幕录制/视频源
├── scripts/
│   └── sync-clips.mjs                # 每次渲染前标准化片段
└── src/
    ├── index.ts                      # registerRoot(Root)
    ├── Root.tsx                      # <Composition>注册表——id、schema、defaultProps
    ├── theme.ts                      # COLORS、FONT_STACK、RADIUS、SHADOWS、TIMELINE
    ├── fonts.ts                      # @remotion/google-fonts + 本地@font-face
    ├── Main.tsx                      # 完整时间线合成器(<Sequence>块)
    ├── components/
    │   ├── Reveal.tsx                # 淡入+上移包装器(delay/duration/rise)
    │   ├── Easing.ts                 # EASE_OUT、EASE_IN_OUT(贝塞尔)
    │   ├── ProgressBar.tsx           # 固定在底部的4阶段指示器
    │   └── VideoPlaceholder.tsx      # 带有插槽标签的灰色卡片,稍后替换为OffthreadVideo
    └── scenes/
        ├── OpeningTitle.tsx          # 每个文件一个场景,每个都是<AbsoluteFill>
        ├── ProductReveal.tsx
        ├── AgentLoop.tsx
        └── ...

为什么这样布局:场景是独立的(易于单独渲染和迭代),共享的视觉语言存在于theme.ts + components/中,因此外观保持一致,而Root.tsx是哪些内容可渲染的单一事实来源。

合成模式(仔细阅读)

每个场景导出三样东西:

  1. 一个zod schema——定义Remotion Studio中的属性面板UI(滑块、下拉菜单)。
  2. 一个*_DEFAULTS常量——当此场景嵌入到完整时间线中时,由Main.tsx使用的值。
  3. React组件本身,类型为React.FC<Props>。
// src/scenes/ProductReveal.tsx
import { z } from "zod";

export const productRevealSchema = z.object({
  titleSize:     z.number().min(40).max(280),
  subtitleSize:  z.number().min(14).max(80),
  outerPaddingV: z.number().min(0).max(200),
});
export type ProductRevealProps = z.infer<typeof productRevealSchema>;

export const PRODUCT_REVEAL_DEFAULTS: ProductRevealProps = {
  titleSize: 168,
  subtitleSize: 64,
  outerPaddingV: 80,
};

export const ProductReveal: React.FC<ProductRevealProps> = (p) => { ... };

然后在Root.tsx中,使用内联副本的默认值注册它:

<Composition
  id="ProductReveal"
  component={ProductReveal}
  durationInFrames={120}
  fps={30}
  width={1920}
  height={1080}
  schema={productRevealSchema}
  defaultProps={{
    // ⚠ PRODUCT_REVEAL_DEFAULTS的内联副本——Remotion Studio的
    // “Save default props”通过AST操作写回此对象。请保持
    // 与上面导出的常量同步。
    titleSize: 168,
    subtitleSize: 64,
    outerPaddingV: 80,
  }}
/>

为什么重复: Remotion Studio的“Save default props”按钮通过AST操作编辑Root.tsx中的defaultProps={…}字面量。它无法重写导入的常量。因此,内联副本是Studio会修改的那个,而导出的*_DEFAULTS是Main.tsx读取的那个。当Studio写入新值时,将它们复制到导出的常量中,以便完整时间线渲染也使用它们。这是references/pitfalls.md中的陷阱#4。

动画原语(你实际需要的小集合)

Remotion中的所有动画都是useCurrentFrame() + interpolate()。没有内部时钟,没有“播放”——每一帧都是frame的纯函数。

相关技能