关于 testimonial-video
将书面评论、引言和客户证言制作成短篇口碑视频的视频技能。重点在于按阅读顺序呈现文字、准确显示评分与署名,并用可复用的 Remotion 模板批量处理评论。
主要功能
- 01按阅读顺序呈现引言
- 02原文引言与短语强调
- 03支持小数评分的星级动画
- 04作者署名信息栏
- 05基于属性的批量渲染
适用场景
- 01将客户评论制作成短片
- 02为证言添加真实评分动画
- 03根据评论列表批量生成视频
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ iart-ai/ ad-video-skills --skill testimonial-video安装后在 Claude Code 中输入/testimonial-video确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdreferences/batch-and-typography.mdquote-card.md详细介绍
客户评价视频
将书面引言、评价或客户推荐语制作成简短、可信的社交证明短片。重点在排版,而非炫技:设计简洁的引言卡片,让文字按阅读顺序呈现,在恰当时机突出关键短语,让星级填充至实际评分,最后由作者署名。一个由 props 驱动的卡片设计,就能为列表中的每条评价制作视频。
适用场景
- 客户评价 → 6–12 秒的竖屏/信息流短片(核心用途)。
- 带作者姓名、职位、头像和公司名称的引言或客户推荐图。
- 动态星级评分(包括 4.5 等半星/小数评分)。
- 批量制作:评价列表/CSV → 每条评价生成一个视频,使用同一模板。
不要用它制作促销/折扣广告或通用广告创意——此技能严格面向引言/社交证明场景。
唯一准则:信任先于动效
客户推荐语要发挥作用,就得让人觉得真实,而不是精心制作。克制带来可信度;过度动画则让人觉得像广告,容易被跳过。
- 按阅读顺序呈现。 眼睛必须读完一行,下一行才能出现。错开各行(或分句),不要一次性显示所有文字,也不要为了视觉效果打乱顺序。
- 逐字引用原文。 不要改述、删掉句子中间的内容,也不要编造评分。若要突出某个短语,它必须是客户原话。
- 作者就是证明。 没有可明确归属的真人,引言就只是一句口号。姓名 + 职位 + 公司名称(若有真实头像也一并提供)是必不可少的。
引言卡片的构成
| 元素 | 作用 | 时间安排 |
|---|---|---|
| 引号装饰 | 在读者看到文字前表明“这是引言” | 第 0 帧,先缩放/淡入 |
| 引言正文 | 逐行呈现客户推荐语 | 错开显示,每行间隔约 6–10 帧 |
| 强调短语 | 最能打动人的那句短语 | 所在行稳定后再出现 |
| 星级评分 | 填充至实际分数的评分 | 引言出现后从左→右填充 |
| 作者信息块 | 姓名/职位/公司/头像 | 最后署名,向上滑入 |
按此顺序构建,也按此顺序呈现。观众先读引言并相信它,再看到评分,最后了解是谁说的。
错开呈现各行
将引言拆分成多行(或多个分句),然后错开每行的入场时间。在 Remotion 中,通过 useCurrentFrame() 驱动每一行,确保渲染结果确定——不要使用 CSS transition 或 JS 计时器,否则会与逐帧渲染器不同步。
import { useCurrentFrame, spring, useVideoConfig } from "remotion";
const QuoteBody = ({ lines, startAt = 8, stagger = 6 }) => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
return (
<blockquote>
{lines.map((line, i) => {
const enter = spring({ frame: frame - startAt - i * stagger, fps,
config: { damping: 200 } }); // 0→1, no overshoot
return (
<span key={i} style={{ display: "block",
opacity: enter,
transform: `translateY(${(1 - enter) * 14}px)` }}>
{line}
</span>
);
})}
</blockquote>
);
};
保持动效语言一致:每一行都使用相同的缓动、相同的 14px 上移幅度。只有保持一致,速度才会显得自信。完整构图请参见 references/quote-card.md。
对关键短语进行动态强调
选出最能体现客户推荐语价值的一句短语(例如“每周为我们节省了 10 小时”),等它所在的行稳定后再呈现——可以用高亮扫过、字重变化或颜色跳变来强调。若强调动效与文字呈现争抢注意力,两者的效果都会被抵消。
const sweep = interpolate(frame, [hlStart, hlStart + 10], [0, 100],
{ extrapolateLeft: "clamp", extrapolateRight: "clamp" });
// a highlighter wiping in behind the phrase, left→right
<mark style={{ background:
`linear-gradient(90deg, var(--accent) ${sweep}%, transparent ${sweep}%)`,
color: "inherit", padding: "0 .08em" }}>{phrase}</mark>
每条引言最多强调一个片段。两个高亮等于没有高亮。
动态星级评分(小数评分)
显示实际分数,包括半星。用一整行星形字形作为遮罩,再将填充图层擦除至 rating / max 的宽度——这样 4.5 和 5.0 都能显示得很清晰,无需使用半星图片素材。
const StarRating = ({ rating, max = 5, fillStart = 30, fillDur = 14 }) => {
const frame = useCurrentFrame();
const target = (rating / max) * 100;
const w = interpolate(frame, [fillStart, fillStart + fillDur], [0, target],
{ extrapolateLeft: "clamp", extrapolateRight: "clamp" });
return (
<div className="stars" role="img" aria-label={`${rating} out of ${max} stars`}>
<div className="track">★★★★★</div>
<div className="fill" style={{ width: `${w}%` }}>★★★★★</div>
</div>
);
};
.stars { position: relative; display: inline-block; font-size: 40px; letter-spacing: 4px; }
.track { color: rgba(255,255,255,.22); }
.fill { position: absolute; inset: 0; overflow: hidden; white-space: nowrap;
color: var(--accent); } /* clipped by width → fractional fill */
引言呈现完毕后,从左向右填充星星。文字出现前绝不要让星星动起来——评分必须让人觉得是赢得的,而非预先设定的。始终将 aria-label 设为实际评分。
作者信息块
最后署名。信息块在星星下方向上滑入,然后保持静止——正是这份静止,让署名读起来像事实。
<figcaption className="author">
{avatar && <img src={avatar} alt="" className="avatar" />}
<div>
<span className="name">{name}</span>
<span className="role">{role}{company && `, ${company}`}</span>
</div>
</figcaption>
使用真实头像,或者不使用头像——通用占位人脸会直接摧毁信任。姓名是信息块中最醒目的内容;职位/公司名称则应采用次要字重。
Template × reviews — 每条评价对应一个视频
收益:让每个字段都成为 prop,不硬编码任何内容,然后为每条评价渲染一次。
export const Testimonial = ({ quote, highlight, rating, name, role, company, avatar }) => { /* … */ };
for f in reviews/*.json; do
npx remotion render Testimonial "out/$(basename "$f" .json).mp4" --props="$f"
done
将颜色、字体、引号样式和布局放在同一个主题对象中,这样 50 条用户评价都能保持品牌风格统一,只需更改文字和评分。有关评价数据结构、CSV→props 解析、引号排版技巧(弯引号、悬挂标点、分行和孤行控制)以及批处理脚本,请参阅 references/batch-and-typography.md。
输出检查清单
- 文本行按阅读顺序依次显现;入场动效保持一致,间隔约 6–10 帧。
- 引言原文照录;恰好有一个强调片段,并在该行稳定后出现。
- 引言结束后,星星按实际评分填充(支持半星),且
aria-label正确。 - 最后显示作者信息块(姓名 + 职务 + 公司,使用真实头像或不使用头像),显示后保持静止。
- 每个动画值都由
useCurrentFrame()派生,不使用 CSS/JS 计时器。 - 每个字段都是 prop;同一个模板可渲染文件夹中的每条评价。
交付与验证(渲染静帧 → 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。
输出要求:
- 将 Remotion
Testimonial注册为<Composition>(附带 zodschema+defaultProps),所有值均由帧驱动(不使用 CSS transitions / JS 计时器 /Date.now()/Math.random())。 - 交付物 = 每条评价、每种宽高比对应的渲染结果
out/*.mp4(以及项目 + 评价数据,以便用户用新的引言重新渲染)。
验证流程 — 渲染静帧 → 检查 → 编码。 先渲染体积小的 PNG;使用随附评价的 props 渲染,而不只是 defaultProps。
# Frame-exact stills across the reveal order: quote → stars → author
npx remotion still Testimonial out/f-quote.png --frame=30 --props=reviews/r1.json # lines in reading order, emphasis span
npx remotion still Testimonial out/f-stars.png --frame=48 --props=reviews/r1.json # stars filled to the REAL score (e.g. 4.5)
npx remotion still Testimonial out/f-author.png --frame=215 --props=reviews/r1.json # author block signed off, holding still
# inspect each: fidelity (quote VERBATIM, exactly one emphasized span, star fill matches rating, name/role/company exact)
# AND artifacts (text overflow/orphans, off-canvas, author in the 9:16 bottom third, missing font, broken avatar)
多种宽高比 / 批处理 — 批量渲染列表前,先在每种目标宽高比下验证同一条评价。 布局问题(引言溢出、作者信息被裁切)会在每条评价 × 每种宽高比中重复出现;先发现并修复一次。
for ar in 9x16 1x1 16x9; do # one representative review, every aspect
npx remotion still Testimonial "out/r1-${ar}.png" --frame=215 \
--props=reviews/r1.json --props-merge="{\"aspect\":\"${ar}\"}"
done
# stills clean in all aspects? → then batch-render the list:
for f in reviews/*.json; do id=$(basename "$f" .json); for ar in 9x16 1x1 16x9; do
npx remotion render Testimonial "out/${id}-${ar}.mp4" --props="$f" --props-merge="{\"aspect\":\"${ar}\"}"
done; done
npx remotion render Testimonial out/demo.gif --codec=gif --props=reviews/r1.json # README demo
完成前:
npx remotion still能在引言 / 星星 / 作者信息处正常渲染,没有错误,也没有缺失字体或头像。- 引言原文照录且有一个强调片段;星星按实际评分填充;姓名 / 职务 / 公司准确无误,并位于安全区域内(避开 9:16 画面底部三分之一)。
- 仅使用帧驱动;不使用 CSS/JS 计时器、
Date.now()或Math.random()。 - 随附评价的 props 能正确渲染(不只是
defaultProps);aria-label包含实际评分。 - 批处理前,先验证一条评价在 9:16 + 1:1 + 16:9 下的效果;MP4 均可播放;(可选)为 README 提供 GIF。
参考文件
references/quote-card.md— 完整且可运行的 RemotionTestimonialcomposition:错落的逐行显现、关键词高亮扫过、分数星级填充、作者信息块、主题对象,以及适用于 9:16 卡片的时间安排图。另附无需依赖的 HTML/CSS 版本。references/batch-and-typography.md— 评价 prop 数据结构、CSV/JSON→props 解析与验证、引言排版技巧(弯引号、悬挂引号、按行 / 分句拆分、孤行控制、动态显示时的易读性)、星级评分的无障碍设计,以及用于批量渲染 N 个视频的 template×reviews 脚本。