关于 promo-video
promo-video 是用于制作 6–15 秒促销短片的技能,面向需要发布折扣和限时优惠的营销团队。它以数据驱动的 Remotion 模板呈现单一优惠,并强调价格准确、逐帧动画和渲染验证。
主要功能
- 01生成折扣与促销码短片
- 02同步呈现划线原价与新价
- 03按真实截止时间展示紧迫感
- 04用优惠数据批量渲染视频
- 05逐帧检查并验证 MP4
适用场景
- 01制作黑色星期五或闪购广告
- 02展示商品原价、折后价与折扣
- 03为优惠码和截止日期制作片尾
- 04从商品价格表批量生成促销视频
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ iart-ai/ ecommerce-video-skills --skill promo-video安装后在 Claude Code 中输入/promo-video确认已加载。
附带文件README.mdreferences/promo-components.md
详细介绍
促销视频
制作一支节奏明快的 6–15s 促销短片,宣布一项优惠并促使观众立即行动:亮出折扣,展示原价→现价并划掉原价,让促销码和截止时间清晰易读,最后以 CTA 收尾。这是优惠公告,不是功能广告,也不是用户评价。要有活力、数字准确、营造紧迫感。
适用场景
- 亮出折扣/百分比优惠(“40% OFF”、“$20 off”)。
- 展示原价→现价,并为原价添加动画删除线。
- 黑色星期五/限时闪购/清仓/上市首周/季节性促销短片。
- 亮出促销码,并注明截止时间或倒计时。
- 将同一促销模板用于多个商品/优惠(价格表 → N 条视频)。
制作效果广告变体时使用 ad-creative-video;呈现客户引言时使用 testimonial-video。聚焦优惠本身。
节奏安排
促销短片时长短、顺序明确。每个节拍只做一件事;绝不把两件事堆在一起。
| 节拍 | 作用 | 时长预算(以 10s 计) |
|---|---|---|
| 开场钩子 | 品牌 + 场合(“BLACK FRIDAY”)骤然亮相 | 0–1.5s |
| 亮出折扣 | 醒目的数字亮相(“40% OFF”) | 1.5–4s |
| 原价→现价 | 划掉原价,现价逐步倒数 | 4–7s |
| 产品 | 一个主视觉镜头,展示促销商品 | (叠加在价格画面下方,4–8s) |
| 促销码 + 紧迫感 | 促销码 + 截止时间,静止展示 | 7–9s |
| CTA | “SHOP NOW” + URL,清晰定格 | 9–10s |
6s 版本节奏要更紧凑(删去产品节拍);15s 版本则可放宽节奏(让每个节拍有舒展空间)。绝不要延长开场钩子。
两条不可妥协的规则
- 数字就是信息,必须准确。 价格和百分比必须通过计算得出,绝不能手动重复填写。根据
was和折扣推导出now和% off,确保它们不会互相矛盾。促销视频价格显示错误,还不如不做视频。货币四舍五入到分,使用Intl.NumberFormat格式化,并使用tabular-nums,避免数字在倒计时期间抖动。 - 一项优惠,每帧聚焦一件事。 一个折扣、一个促销码、一个 CTA。相互竞争的优惠会削弱紧迫感。如果有两项优惠,就制作两支视频。
标志性手法:原价→现价,加删除线
三种动画要同步进行:删除线划过原价,新价格倒数到最终数值,并以轻微过冲强调落点。三者都由 useCurrentFrame() 驱动,绝不要使用 CSS 过渡或 JS 计时器,确保服务端渲染时也不会不同步。
import { useCurrentFrame, interpolate, spring, useVideoConfig } from "remotion";
const usd = new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" });
export const PriceDrop = ({ was = 79.0, now = 47.4, startAt = 30 }) => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
const f = frame - startAt;
// 1. strike-through line draws L→R over ~0.4s
const strike = interpolate(f, [0, 12], [0, 100], { extrapolateLeft: "clamp", extrapolateRight: "clamp" });
// 2. new price counts from `was` down to `now`, eased
const t = spring({ frame: f - 8, fps, config: { damping: 18, mass: 0.6 } });
const shown = was + (now - was) * t;
// 3. landing pop on the final value
const pop = interpolate(t, [0.9, 1], [1.12, 1], { extrapolateLeft: "clamp", extrapolateRight: "clamp" });
return (
<div style={{ fontVariantNumeric: "tabular-nums", textAlign: "center" }}>
<span style={{ position: "relative", opacity: 0.55, fontSize: 48 }}>
{usd.format(was)}
<span style={{ position: "absolute", left: 0, top: "50%", height: 4, background: "#ff3b3b",
width: `${strike}%`, transformOrigin: "left" }} />
</span>
<div style={{ fontSize: 96, fontWeight: 800, transform: `scale(${pop})` }}>
{usd.format(shown)}
</div>
</div>
);
};
顺序很重要:先划掉原价,再亮出现价。在同一时刻划线和倒数,会显得像故障。有关绑定到 props 的完整组合(折扣徽章、促销码亮相、倒计时、CTA),请参阅 references/promo-components.md。
亮出折扣和促销码
百分比是屏幕上最醒目的元素,比品牌和产品都大。通过计算得出,不要手动填写。
const pct = Math.round((1 - now / was) * 100); // 79 → 47.4 ⇒ 40
const off = was - now; // for "$X off" framing
根据价格选择展示方式:高价商品展示百分比(“40% OFF”比“$32 off”更合适);低价商品展示固定金额(“$5 off”比“8% off”更合适)。将促销码显示为看起来可点击的标签(等宽字体、虚线边框、浅色背景),并保持静止——移动的促销码难以阅读,也不便截图。能体现紧迫感的促销码转化效果更好:FLASH40、TODAY20、LASTCHANCE。
真实可信的紧迫感
只有真实的紧迫感才能提升转化。显示明确的截止时间(“周日晚上 11:59 结束”)或看起来实时的倒计时,绝不要使用虚假计时器。观众需要约 2s 才能读完有时限的优惠,因此要让截止时间画面停留足够久,不要一闪而过。将倒计时单独放在促销码附近一行,不要让它和价格争抢注意力。
// frame → mm:ss remaining, derived from a deadline prop (deterministic per frame)
const remaining = Math.max(0, deadlineSec - frame / fps);
const mm = String(Math.floor(remaining / 60)).padStart(2, "0");
const ss = String(Math.floor(remaining % 60)).padStart(2, "0");
动效风格:充满活力,但不杂乱
促销短片的冲击力来自快速、统一的动效:快速弹簧式入场(damping ~12,带过冲)、在强调处硬切、用一种强调色(鲜艳的红色/绿色)表现节省金额,并在各处重复使用。所有节拍统一使用一种入场曲线,让速度传达自信。避免会削弱紧迫感的漂移/视差效果。如果有配乐,让折扣亮相落在最强的音频节拍上。
模板 × 数据 — 多款产品,一个模板
代码驱动促销内容的优势:价格/优惠表格可为每款产品渲染一个视频,并确保价格准确,因为价格来自数据,而不是由设计师重新输入。将优惠设为输入属性;不要硬编码任何内容。
// one composition, different offer → different video
export const Promo = ({ offer }) => { /* reads offer.was/now/code/deadline/img — no constants */ };
# render the promo for every offer row in /offers
for f in offers/*.json; do
npx remotion render Promo "out/$(basename "$f" .json).mp4" --props="$f"
done
渲染前验证每一行(now < was、优惠码存在、图片存在),这样错误行会立即报错,而不是带着错误价格发布。将颜色/字体/CTA 放在一个主题对象中,让 200 个促销内容始终符合品牌规范,只更改数字。优惠方案、验证和批处理脚本请参阅 references/promo-components.md。
输出检查清单
- 根据
was计算now和% off——绝不重复手动输入;使用tabular-nums进行舍入并通过Intl.NumberFormat格式化。 - 先绘制删除线,再显示新价格;两者都必须是
useCurrentFrame()的纯函数。 - 每个视频只展示一项优惠、一个优惠码和一个 CTA;折扣是最醒目的元素。
- 紧迫感应来自真实的截止时间/倒计时,并持续 ≥2s,而不是虚假的闪烁计时器。
- 所有节拍统一使用一种入场曲线和一种节省金额强调色。
- 将优惠设为输入属性;批量渲染前验证每一行数据(now < was)。
交付与验证(渲染静帧 → MP4)
打包的辅助脚本(
scripts/):使用scripts/contact-sheet.sh sheet.png f-hook.png f-mid.png f-end.png拼接静帧,然后使用scripts/probe-mp4.sh out.mp4 [WxH] [fps]验证编码。请参阅scripts/README.md。
这是重型任务:交付物是 MP4,而不是实时页面。促销内容包含精确金额——验证主要是检查数字是否正确,以及产品图片是否确实显示。
输出约定:
- 一个 Remotion 项目,注册了合成(
<Composition>+ zodschema+defaultProps);折扣揭示、删除线、倒计时和 CTA 都是useCurrentFrame()的纯函数(没有 CSS 过渡、计时器、Date.now())。 - 通过
staticFile()加载产品图片,并使用delayRender/continueRender控制渲染,确保英雄镜头(和品牌字体)在帧渲染前已加载——根据was计算now/% off,绝不重复手动输入。 - 交付物 = 渲染后的
out/*.mp4和项目(针对每一行优惠重新渲染)。
验证流程 — 渲染静帧 → 检查 → 编码。 先渲染成本较低的 PNG,只有确认数字和图片正确后才渲染视频。
# Frame-exact stills WITH THE OFFER PROPS YOU'LL SHIP, not defaultProps
npx remotion still Promo out/f-discount.png --frame=60 --props=offer.json # "40% OFF" big number landed
npx remotion still Promo out/f-price.png --frame=120 --props=offer.json # was struck through, now settled
npx remotion still Promo out/f-cta.png --frame=270 --props=offer.json # code + deadline + CTA end-card
# end frame = durationInFrames - 1 (npx remotion compositions reads it)
检查每张 PNG 的准确性(was/now/% off 精确无误;删除线从原价划向新价;促销码拼写正确;产品图片无误)以及瑕疵(图片空白/未加载、数字抖动或错误、价格溢出/超出画布、删除线位置错误、CTA/优惠码位于标题安全区域之外、宽高比错误/出现黑边)。
# Only after stills are clean:
npx remotion render Promo out/promo.mp4 --props=offer.json
npx remotion render Promo out/promo.gif --props=offer.json --codec=gif # README first-screen proof
批量处理(一个模板,多款产品): 从价格表渲染 N 个视频时,先通过静帧验证一项代表性优惠的属性,再批量渲染整个目录——发现一次错误价格或空白图片,总比把问题发布 N 次好。
完成前:
- 折扣/价格/CTA 静帧均干净渲染——没有错误,且产品图片确实已加载(非空白)。
was/now/% off数值精确(根据was计算);删除线划过原价,新价格稳定显示,优惠码/截止时间正确。- 所有动效都由帧驱动——没有 CSS 过渡/计时器/
Date.now()/Math.random()。 - 实际发布的优惠属性渲染正确,而不只是
defaultProps。 - 完整 MP4 已编码且可播放;(可选)为 README 渲染 GIF。
参考文件
references/promo-components.md— 一个完整且可运行的 Remotion 促销合成,由优惠属性驱动:折扣徽章、was→now 删除线 + 倒计时、促销码标签、实时倒计时和 CTA 结束卡;还包括优惠方案、逐行验证、主题对象,以及针对 N 款产品的模板 × 数据批量渲染脚本。