用途
promo-video 用于制作 6–15 秒的销售促销短视频,宣布单一优惠并促使观众立即行动。它是优惠公告,不是功能广告,也不是客户评价。核心是能量、准确的数字和紧迫感。
适用场景包括:
- 折扣或百分比优惠揭示(如“40% OFF”“$20 off”)。
- was→now 价格下降,带删除线动画。
- 黑色星期五、限时抢购、清仓、发布周、季节性促销。
- 促销码揭示,带截止日期或倒计时。
- 一个促销模板渲染到多个产品/优惠(价格表 → N 个视频)。
如需效果广告变体,使用 ad-creative-video;如需客户评价,使用 testimonial-video。本技能始终围绕优惠本身。
主要能力
叙事弧线
销售短片短促且有序,每个节拍只做一件事,绝不叠加两件事。以 10 秒为例:
- Hook:品牌 + 场合(如“BLACK FRIDAY”)快速切入,0–1.5 秒。
- Discount reveal:大数字落地(如“40% OFF”),1.5–4 秒。
- was→now:旧价格划删除线,新价格递减,4–7 秒。
- Product:一个主视觉镜头,即所售商品(价格下方,4–8 秒)。
- Code + urgency:促销码 + 截止日期,保持静止,7–9 秒。
- CTA:“SHOP NOW” + URL,干净停留,9–10 秒。
6 秒可更紧凑(去掉产品节拍),15 秒可更宽松(让每个节拍呼吸)。Hook 绝不要拉长。
两条不可协商的规则
-
数字就是信息,必须精确。价格和百分比必须计算得出,绝不能重复输入。now 和折扣百分比应从 was 和折扣推导,确保不会互相矛盾。显示错误价格的促销视频比没有视频更糟。货币四舍五入到分,使用 Intl.NumberFormat 格式化,并使用 tabular-nums 使数字在递减过程中不抖动。
-
每个画面一个优惠、一个焦点。单一折扣、单一促销码、单一 CTA。竞争性优惠会扼杀紧迫感。如果有两个优惠,就做两个视频。
标志性动效:was→now 与删除线
三件事同时动画且必须保持同步:删除线横跨旧价格绘制、新价格递减到最终值、落点微过冲加以强调。三者都由 useCurrentFrame() 驱动,绝不使用 CSS transition 或 JS 定时器,以免服务器渲染失步。
顺序很重要:先划旧价格,再降新价格。同时划线和递减会读作故障。
折扣揭示与促销码
百分比是屏幕上最响亮的元素,比品牌大、比产品大。计算它,不要输入它。
根据价格选择框架:较高价商品用百分比(“40% OFF”优于“$32 off”),低价商品用固定金额(“$5 off”优于“8% off”)。促销码以可点击样式的芯片呈现(等宽字体、虚线边框、浅色背景)并保持静止——移动的促销码无法阅读或截图。编码紧迫感的促销码转化更好:FLASH40、TODAY20、LASTCHANCE。
诚实的紧迫感
紧迫感只有在真实时才提升转化。显示具体截止日期(如“Ends Sun 11:59pm”)或看起来实时的倒计时——绝不用假计时器。观众需要约 2 秒阅读时间敏感优惠,因此要停留截止日期节拍,不要一闪而过。倒计时放在促销码附近的独立行,不要与价格赛跑。
动效语言:有能量但不混乱
销售短片靠干脆、一致的运动获得冲击力:快速弹簧入场(阻尼约 12,过冲)、强调处硬切、一个用于节省的强调色(热红/绿)处处复用。所有节拍保持同一条入场曲线,让速度读作自信。避免削弱紧迫感的漂移/视差。如果有配乐,让折扣揭示落在最强音频节拍上。
模板 × 数据:多产品,一模板
代码驱动促销的回报:价格/优惠表为每个产品渲染一个视频,价格保证准确,因为它们来自数据,而非设计师重新输入。将优惠作为输入 prop,不要硬编码任何内容。
渲染前验证每一行(now < was、促销码存在、图片存在),让坏行大声失败,而不是发布错误价格。将颜色/字体/CTA 放在一个主题对象中,使 200 个促销保持品牌锁定,只有数字变化。
使用方式
输出清单
- now 和 % off 从 was 计算——绝不重复输入;四舍五入并用 Intl.NumberFormat 格式化,配合 tabular-nums。
- 删除线先绘制,新价格后下降;两者都是 useCurrentFrame() 的纯函数。
- 每个视频一个优惠、一个促销码、一个 CTA;折扣是最响亮的元素。
- 紧迫感是真实截止日期/倒计时,停留 ≥2 秒,不是假闪烁计时器。
- 所有节拍使用一条入场曲线和一个节省强调色。
- 优惠是输入 prop;每行数据在批量渲染前验证(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,不是实时页面。促销涉及精确金额,验证环节主要是数字是否正确、产品图片是否真的存在。
输出契约:
- 一个注册了 composition 的 Remotion 项目(<Composition> + zod schema + defaultProps);折扣揭示、删除线、倒计时和 CTA 都是 useCurrentFrame() 的纯函数(无 CSS transition、定时器、Date.now())。
- 产品图片通过 staticFile() 加载,用 delayRender/continueRender 门控,确保主视觉镜头(和品牌字体)在帧渲染前就位——now/% off 从 was 计算,绝不重复输入。
- 交付物 = 渲染出的 out/*.mp4 加上项目(按优惠行重新渲染)。
验证循环——渲染静帧 → 检查 → 编码。先做便宜的 PNG,数字和图片正确后再做视频。
用将要发布的优惠 props(而非 defaultProps)渲染帧精确静帧,检查每个 PNG 的保真度(精确的 was/now/% off;was→now 删除线画在旧价格上;促销码拼写正确;产品图片正确)和伪影(图片空白/未加载、数字抖动或错误、价格溢出/出画、删除线画错行、CTA/促销码在标题安全区外、宽高比错误/黑边)。
批量(一模板多产品):渲染价格表 → N 个视频时,先用静帧验证一个代表性优惠的 props,再批量渲染整个目录——一次抓住错误价格或空白图片,胜过发布 N 次。
完成前检查
- 静帧在折扣/价格/CTA 处渲染干净——无错误,产品图片确实加载(非空白)。
- was/now/% off 精确(从 was 计算);删除线在旧价格上,新价格已落定,促销码/截止日期正确。
- 所有运动由帧驱动——无 CSS transition / 定时器 / Date.now() / Math.random()。
- 发布的优惠 props 渲染正确,而不仅是 defaultProps。
- 完整 MP4 已编码并可播放;(可选)为 README 渲染 GIF。
参考文件
references/promo-components.md —— 一个完整可运行的 Remotion 促销 composition,由 offer prop 驱动:折扣徽章、was→now 删除线 + 递减、促销码芯片、实时倒计时和 CTA 结束卡——外加 offer schema、逐行验证、主题对象,以及用于 N 个产品的模板×数据批量渲染脚本。
限制
本技能聚焦于单一优惠的促销公告,不适用于效果广告变体或客户评价视频。紧迫感必须真实,不得使用假计时器。所有价格和百分比必须计算得出,不得重复输入。交付物为 MP4,不是实时页面。