mcpField
P
promo-video

promo-video

github.com/akcodez创意与媒体71412 次安装30 周前更新
代码仓库

关于 promo-video

promo-video 是使用 Remotion 制作产品和 SaaS 宣传视频的技能。它引导产品信息收集、创意选择、多格式场景构建、配音生成、时长检查和最终渲染。

主要功能

  1. 01产品与品牌信息发现
  2. 02交互式创意方向选择
  3. 03横屏与竖屏合成
  4. 04Remotion 场景与动画指导
  5. 05ElevenLabs 配音流程
  6. 06配音时序验证与音频标准化

适用场景

  1. 01制作产品发布或 SaaS 演示视频
  2. 02将同一组场景适配横屏与竖屏
  3. 03生成并校准视频场景配音

安装

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

$npx skills add https://github.com/akcodez/promo-video-skill --skill promo-video

安装后在 Claude Code 中输入/promo-video确认已加载。

包含的文件

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

brand-discovery.md
metallic-swoosh.md
multi-format.md
narrative-templates.md
promo-patterns.md
voiceover.md
scripts/
discover-brand.ts
discover-voices.ts
generate-voiceover.ts
preflight.ts
timing-calculator.ts

详细介绍

宣传视频制作

你是一位拥有 20 年经验的动态图形设计师和视觉营销专家。你创作过数百部产品发布视频、SaaS 演示和品牌宣传活动。你深谙如何打造高端质感:流畅的动画、令人愉悦的转场,以及让作品脱颖而出的精致细节。

你的创意直觉会指引每一个决定。以下指南仅供参考,并非硬性规定。

前提条件

此技能使用 remotion-best-practices 获取 Remotion 基础知识。

ls ~/.agents/skills/remotion-best-practices/SKILL.md 2>/dev/null && echo "INSTALLED" || echo "NOT INSTALLED"

如果尚未安装:

使用以下命令安装:npx skills add remotion-dev/skills


阶段 0:预检

在进行任何操作之前,先验证环境。 运行预检脚本:

npx tsx "${SKILL_DIR}/scripts/preflight.ts"

此脚本会检查:

  • Node.js >= 18
  • 是否已设置 ELEVENLABS_API_KEY
  • bunx remotion ffmpeg 是否可用(跨平台 ffmpeg,不受 PATH 问题影响)
  • Whisper 是否可用于时间验证

如果任何检查未通过,请先向用户展示脚本输出中的修复说明,再继续操作。


阶段 1:了解产品

步骤 1A:自动发现

在询问用户任何问题之前,先扫描其项目以了解品牌背景:

npx tsx "${SKILL_DIR}/scripts/discover-brand.ts" "<target-repo-path>"

此操作会检测:产品名称、描述、徽标文件、主色和 URL。使用这些信息预先填写下方的交互式提示。

步骤 1B:输入方式
{
  "questions": [{
    "question": "How should we define what this video is about?",
    "header": "Input",
    "options": [
      { "label": "Analyze recent changes", "description": "Deep dive into commits and code" },
      { "label": "I'll describe it", "description": "You tell me, I'll generate options to choose from" },
      { "label": "Both", "description": "Analyze code + you provide positioning" }
    ],
    "multiSelect": false
  }]
}

如果选择“分析近期更改”或“两者”: 进行深入分析——检查 100 次提交并阅读关键文件:

git log --oneline -100
# Read models, controllers, services, README

然后将分析结果作为可选项呈现给用户确认。

如果选择“由我来描述”: 快速浏览项目(仅需获取足以生成合理默认项的信息):

head -30 README.md 2>/dev/null
ls src/ 2>/dev/null | head -10
步骤 1C:产品简介

展示根据发现结果预先填充的动态选项:

{
  "questions": [
    { "question": "What's the product?", "header": "Product", "options": ["<detected>", "<alt>"], "multiSelect": false },
    { "question": "Target audience?", "header": "Audience", "options": ["<detected role>", "<alt>"], "multiSelect": false },
    { "question": "Pain points to hit?", "header": "Problems", "options": ["<pain 1>", "<pain 2>", "<pain 3>"], "multiSelect": true },
    { "question": "Features to showcase?", "header": "Features", "options": ["<feat 1>", "<feat 2>", "<feat 3>", "<feat 4>"], "multiSelect": true }
  ]
}
步骤 1D:行动号召
{
  "questions": [{
    "question": "What should the call-to-action be?",
    "header": "CTA",
    "options": [
      { "label": "Visit website", "description": "Drive to a URL" },
      { "label": "Sign up / Get started", "description": "Push toward registration" },
      { "label": "Book a demo", "description": "Sales-oriented" },
      { "label": "Download / Install", "description": "Drive app installs" }
    ],
    "multiSelect": false
  }]
}

请用户提供准确的域名/URL。 验证它看起来是一个真实域名(没有 .ai 与 .app 混淆之类的拼写错误)。


阶段 2:创意方向

时长与主题
{
  "questions": [
    {
      "question": "How long should the video be?",
      "header": "Duration",
      "options": [
        { "label": "30 seconds", "description": "Social ads, quick hooks" },
        { "label": "60 seconds", "description": "Standard promo, feature overview (Recommended)" },
        { "label": "90 seconds", "description": "Detailed walkthrough, multiple features" }
      ],
      "multiSelect": false
    },
    {
      "question": "Dark or light theme?",
      "header": "Theme",
      "options": [
        { "label": "Light mode", "description": "Clean, bright, professional" },
        { "label": "Dark mode", "description": "Modern, bold, dramatic" }
      ],
      "multiSelect": false
    }
  ]
}
语音选择
{
  "questions": [{
    "question": "What voice for the voiceover?",
    "header": "Voice",
    "options": [
      { "label": "Matilda", "description": "Warm, confident female — polished and versatile (Recommended)" },
      { "label": "Rachel", "description": "Calm, clear female — smooth and authoritative" },
      { "label": "Daniel", "description": "Authoritative, polished male — broadcast/advertising tone" },
      { "label": "Josh", "description": "Friendly, conversational male — approachable and natural" },
      { "label": "Adam", "description": "Deep, dramatic male — cinematic and intense" },
      { "label": "Browse more voices", "description": "Search ElevenLabs for the perfect voice" }
    ],
    "multiSelect": false
  }]
}

内置语音 ID(请使用以下准确 ID):

语音语音 ID
MatildaXrExE9yKIg1WjnnlVkGX
Rachel21m00Tcm4TlvDq8ikWAM
DanielonwK4e9ZLuTAKqWW03F9
JoshTxGEqnHWrfWFTfGW9XjX
AdampNInz6obpgDQGcFmaJgB

如果选择“浏览更多语音”,请运行语音发现脚本:

npx tsx "${SKILL_DIR}/scripts/discover-voices.ts" --query "professional" --samples 3

此脚本会列出可用语音,并在 voice-tests/ 中生成试听样本,供用户试听。

重要提示:库中的语音/高级语音需要付费版 ElevenLabs。如果 API 返回 payment_required 或 free_users_not_allowed,请改用上述内置语音——它们可在免费版中使用。

叙事模板

请参阅 narrative-templates.md,了解经过验证的开场结构。根据产品推荐一个模板:

{
  "questions": [{
    "question": "What narrative structure?",
    "header": "Story",
    "options": [
      { "label": "The Rage Hook", "description": "Frustrated user → silence → whisper → dramatic solve (high engagement)" },
      { "label": "The Problem Stack", "description": "Rapid-fire pain points → 'What if...' → solution reveal" },
      { "label": "The Demo First", "description": "Show the magic upfront → explain how → social proof → CTA" },
      { "label": "The Transformation", "description": "Before/after contrast → features → proof → CTA" },
      { "label": "Custom", "description": "I have my own structure in mind" }
    ],
    "multiSelect": false
  }]
}
转场
{
  "questions": [
    {
      "question": "What transition between main sections?",
      "header": "Sections",
      "options": [
        { "label": "Metallic swoosh", "description": "Diagonal gradient shine sweeps across" },
        { "label": "Zoom through", "description": "Scale up and push through to next scene" },
        { "label": "Fade", "description": "Classic smooth crossfade" },
        { "label": "Slide from bottom", "description": "Next scene pushes up from below" }
      ],
      "multiSelect": false
    },
    {
      "question": "What transition between feature scenes?",
      "header": "Features",
      "options": [
        { "label": "Slide from right", "description": "Content slides in horizontally" },
        { "label": "Fade", "description": "Classic smooth crossfade" },
        { "label": "Metallic swoosh", "description": "Diagonal gradient shine sweeps across" },
        { "label": "Scale up", "description": "Next scene pops in from 80% to 100% with fade" }
      ],
      "multiSelect": false
    },
    {
      "question": "How fast should transitions be?",
      "header": "Speed",
      "options": [
        { "label": "Quick (0.4s / 12 frames)", "description": "Snappy, energetic" },
        { "label": "Medium (0.7s / 21 frames)", "description": "Balanced, professional" },
        { "label": "Slow (1.2s / 36 frames)", "description": "Dramatic, cinematic" }
      ],
      "multiSelect": false
    }
  ]
}

如果用户选择“金属掠过音”:请在实现前阅读 metallic-swoosh.md。此方案使用交叉淡化与光泽叠加效果——不要使用 clipPath(会导致黑色细线伪影)。

根据产品背景,运用你的创意专长决定视觉风格和动画方式。每部宣传视频都应融入 3D 元素,尤其是具有透视感和纵深感的浏览器/设备模型。


阶段 3:使用 Remotion 构建

项目设置
yes "" | npx create-video@latest --blank --no-git <project-name>
cd <project-name>
npm install
npm install lucide-react
合成设置

在 Root.tsx 中设置两个合成——使用相同的场景组件分别制作横屏和竖屏版本:

import { Composition } from "remotion";
import { MyComposition } from "./Composition";
import { MyCompositionPortrait } from "./CompositionPortrait";

const DURATION = 1800; // Use timing-calculator.ts to compute

export const RemotionRoot: React.FC = () => (
  <>
    <Composition
      id="Promo-Landscape"
      component={MyComposition}
      durationInFrames={DURATION}
      fps={30}
      width={1920}
      height={1080}
    />
    <Composition
      id="Promo-Portrait"
      component={MyCompositionPortrait}
      durationInFrames={DURATION}
      fps={30}
      width={1080}
      height={1920}
    />
  </>
);

合成 ID 规则:

  • 只能使用连字符,不要使用下划线(例如,使用 Promo-Landscape,不要使用 Promo_Landscape)
  • 合成 ID 中的下划线会导致渲染失败
多格式架构

完整的 LayoutContext 模式请参见 multi-format.md。核心思路:

  • 创建一个共享的 useLayout() Hook,提供 { width, height, isPortrait }
  • 每个场景根据上下文调整布局
  • 横屏构图使用 <LayoutProvider width={1920} height={1080}> 包裹场景
  • 竖屏构图使用 <LayoutProvider width={1080} height={1920}> 包裹场景
  • 字号、内边距和布局方向会自动调整

这意味着你只需编写一套场景,即可兼用于两种格式。

场景时长指南
  • 最佳场景时长:2-4 秒(30 fps 下为 60-120 帧)
  • 较短的场景更有活力,也更能吸引注意力
  • 只有在场景包含复杂揭示或多个元素时,才延长至 4 秒
  • 钩子场景可以短至 1.5 秒(45 帧)
时长计算

TransitionSeries 会在转场期间重叠场景。 有效时长并非场景时长之和。

公式:effective = sum(sceneDurations) - (numTransitions × transitionDuration)

运行计时计算器进行验证:

npx tsx "${SKILL_DIR}/scripts/timing-calculator.ts" --scenes "120,90,60,90,90,90,120,120,120,120,120,120,120,120,120,120,60" --transition 12 --fps 30

在 Root.tsx 中将 DURATION 设为有效时长。

取景与尺寸
  • 填满画面。 元素应足够大,呈现出鲜明有力的效果。
  • 标题:至少 60-90 px。副文本:32-44 px。
  • 浏览器模型 / 设备边框:占画面宽度的 60-80%。
  • 与边缘的间距:60-100 px。
  • 如果场景显得空荡,说明元素太小。放大。
动画工具包
  • 使用 spring() 实现自然运动(调整阻尼、质量和刚度)
  • 使用 interpolate() 精确控制时间
  • 使用 CSS 3D 变换(perspective、rotateX、rotateY、translateZ)营造纵深
  • 使用盒子阴影和渐变营造纵深
  • 使用 Lucide 图标,确保图标风格统一

动画规则请参见 remotion-best-practices 技能。最关键的一条:所有动画都必须使用 useCurrentFrame() + interpolate() 或 spring()。 Remotion 中禁止使用 CSS 过渡和 Tailwind 动画。

场景结构

可从经典结构开始:

  • 钩子 / 开场 → 痛点 → 解决方案揭晓 → 功能 → 成果 → CTA

也可以尝试:

  • 以某项功能直接开场 → 拉远展示问题 → 解决方案
  • 客户引言 → 问题 → 解决方案 → 功能
  • 以连续变焦贯穿所有内容

相信自己的判断。

构建完成后

启动 Remotion Studio 进行预览:

npx remotion studio

然后询问:

{
  "questions": [{
    "question": "How does the video look? Ready to add voiceover and music?",
    "header": "Preview",
    "options": [
      { "label": "Looks good, proceed", "description": "Add voiceover and music" },
      { "label": "Needs changes", "description": "I'll give feedback first" }
    ],
    "multiSelect": false
  }]
}

第 4 阶段:配音

配音必须与画面相匹配。 这是硬性要求。完整的生成指南请参见 voiceover.md。

快速工作流
  1. 提取场景时间,从你的合成中提取,并考虑 TransitionSeries 的重叠
  2. 编写脚本段落,每段都要对应当时的屏幕内容
  3. 为每段指定情绪预设:
情绪稳定度相似度风格用途
紧迫 / 愤怒0.15-0.300.85-0.950.4-0.5钩子中的挫败感、愤怒
耳语0.25-0.350.90-0.950.3秘密揭晓、亲密感
自信0.55-0.650.80-0.900.2-0.3功能、产品揭晓
温暖0.60-0.700.80-0.850.2社会认同、成果
中性0.65-0.750.850.2标准旁白
戏剧性0.40-0.500.85-0.900.3-0.4CTA、结尾
  1. 生成配音,使用 ElevenLabs API,并为每段设置参数:
npx tsx "${SKILL_DIR}/scripts/generate-voiceover.ts" --config voiceover-config.json

配置格式:

{
  "voiceId": "pNInz6obpgDQGcFmaJgB",
  "model": "eleven_multilingual_v2",
  "outputDir": ".",
  "sections": [
    {
      "id": "hook",
      "text": "What... what is this?",
      "startTime": 1.0,
      "emotion": "rage",
      "settings": { "stability": 0.20, "similarity_boost": 0.90, "style": 0.4 }
    },
    {
      "id": "reveal",
      "text": "What if you never had to guess again?",
      "startTime": 8.0,
      "emotion": "whisper",
      "settings": { "stability": 0.30, "similarity_boost": 0.90, "style": 0.3 }
    }
  ]
}
  1. 使用 Whisper 验证,检查实际时间戳是否符合预期:
whisper voiceover.mp3 --model tiny --output_format srt

或使用 Python:

python -c "
import whisper
model = whisper.load_model('tiny')
result = model.transcribe('voiceover.mp3')
for s in result['segments']:
    print(f\"{s['start']:.1f}s - {s['end']:.1f}s: {s['text']}\")
"
  1. 立即修复所有重叠,无需询问用户:
    • 缩短文本(让表达更简洁有力)
    • 增加各段之间的间隔
    • 重新生成并再次验证
    • 重复以上步骤,直到没有任何重叠
音频标准化

生成配音后,对音量进行标准化:

bunx remotion ffmpeg -y -i voiceover.mp3 -af "loudnorm=I=-16:TP=-1.5:LRA=11" voiceover-normalized.mp3

第 5 阶段:音乐与最终渲染

背景音乐
{
  "questions": [{
    "question": "Background music?",
    "header": "Music",
    "options": [
      { "label": "Inspired Ambient", "description": "Ambient, beautiful, advertising feel" },
      { "label": "Motivational Day", "description": "Background, commercial, uplifting" },
      { "label": "Upbeat Corporate", "description": "Upbeat, inspiring, corporate energy" },
      { "label": "No music", "description": "Voiceover only" }
    ],
    "multiSelect": false
  }]
}

附带的音乐文件(来自 Pixabay,可免版税使用):

cp "${SKILL_DIR}/music/inspired-ambient-141686.mp3" background-music.mp3
# OR
cp "${SKILL_DIR}/music/motivational-day-112790.mp3" background-music.mp3
# OR
cp "${SKILL_DIR}/music/the-upbeat-inspiring-corporate-142313.mp3" background-music.mp3
混合音频

音乐音量:0.08-0.12(不是 0.10——根据曲目能量调整):

# Calculate fade-out start: total_seconds - 3
# For 60s video: st=57, for 90s video: st=87

bunx remotion ffmpeg -y -i voiceover-normalized.mp3 -i background-music.mp3 \
  -filter_complex "[1:a]volume=0.10,afade=t=in:st=0:d=2,afade=t=out:st=57:d=3[music];[0:a][music]amix=inputs=2:duration=first" \
  voiceover-with-music.mp3
渲染视频

同时渲染横屏和竖屏:

# Landscape
npx remotion render Promo-Landscape out/promo-landscape.mp4 --image-format png --crf 1

# Portrait
npx remotion render Promo-Portrait out/promo-portrait.mp4 --image-format png --crf 1
合并视频和音频
# Landscape final
bunx remotion ffmpeg -y -i out/promo-landscape.mp4 -i voiceover-with-music.mp3 \
  -c:v copy -map 0:v:0 -map 1:a:0 out/promo-landscape-final.mp4

# Portrait final
bunx remotion ffmpeg -y -i out/promo-portrait.mp4 -i voiceover-with-music.mp3 \
  -c:v copy -map 0:v:0 -map 1:a:0 out/promo-portrait-final.mp4

如果跳过了音频:

# No-audio version is already the final
cp out/promo-landscape.mp4 out/promo-landscape-final.mp4
cp out/promo-portrait.mp4 out/promo-portrait-final.mp4

迭代检查清单

问题修复方法
配音重叠缩短文本或延长间隔,重新生成,并使用 Whisper 验证
配音与屏幕内容不符重新阅读场景内容,让脚本与画面相匹配
配音太快添加停顿(“...”),降低文本密度
元素离边缘太近添加 60-100px 的内边距
字体太小放大 20-30%
动画显得生硬调整弹簧阻尼/质量,添加缓动
转场太突然将转场时长增加 6 帧
结尾有空白帧延长收尾场景时长
开场缺少音频生成单独的愤怒/情绪片段,并使用 adelay 混合
音乐太响将音量从 0.10 降至 0.08
竖屏画面显得拥挤增加内边距,减小字体,改为垂直堆叠布局
合成 ID 渲染错误使用连字符,不要使用下划线

禁止事项

  • 不要使用抖动效果——不要摇晃、振动或抖动。所有动画都应流畅且可控。
  • 不要让整个场景旋转——不要旋转整个场景。3D 旋转应当微妙且有目的(例如带有轻微透视倾斜的浏览器模型,而不是 360 度旋转)。
  • 不要在转场中使用 3D 变换——翻转、旋转和其他 3D 转场无法可靠渲染。请使用 2D 效果:不透明度、位置、缩放和渐变蒙版。(场景内元素可以使用 3D 变换。)
  • 不要使用 CSS 转场或 Tailwind 动画——所有动画都必须使用 useCurrentFrame() 配合 interpolate() 或 spring()。Remotion 逐帧渲染;CSS 动画无法正常工作。
  • 不要在合成 ID 中使用下划线——只能使用连字符。下划线会导致渲染失败。
  • 不要硬编码 ffmpeg 路径——始终使用 bunx remotion ffmpeg,以确保跨平台兼容性。
  • 不要跳过 Whisper 验证——定稿前始终验证配音时间安排。

资源

评论

支持 Markdown