testimonial-video について
書かれたレビューや引用、顧客の証言を短いソーシャルプルーフ動画にするスキルです。読みやすい引用アニメーション、正確な評価と署名、レビューをまとめて処理できる再利用可能なRemotionテンプレートを扱います。
主な機能
- 01読順に沿った引用の表示
- 02原文の引用とフレーズ強調
- 03小数評価に対応する星のアニメーション
- 04投稿者の情報ブロック
- 05props駆動の一括レンダリング
活用シーン
- 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詳細
お客様の声の動画
文章の引用、レビュー、お客様の声を、信頼感のある短いソーシャルプルーフ動画にアニメーション化します。派手さではなく、タイポグラフィの技が重要です。読み進める順に言葉が現れ、適切なタイミングで重要なフレーズが強調され、星が実際の評価に合わせて塗りつぶされ、最後に投稿者が署名する、すっきりとした引用カードを作成します。プロパティで制御する1つのカードデザインから、リスト内のすべてのレビューを動画にできます。
使用するタイミング
- 顧客レビュー → 6~12秒の縦型/フィード向け動画(主な用途)。
- 投稿者の名前、役職、アバター、会社名を添えた引用文やお客様の声のグラフィック。
- 星評価のアニメーション(4.5などの半端な評価も含む)。
- まとめて作成:レビューのリスト/CSV → 同じテンプレートでレビューごとに1本の動画。
セール/割引のプロモーションや汎用的な広告クリエイティブには使用しないでください。このスキルは引用/ソーシャルプルーフに特化しています。
たった1つのルール:動きより信頼感を優先する
お客様の声は、作り込まれた印象ではなく、本物らしく感じられることで役割を果たします。控えめな演出は信頼感につながります。過剰なアニメーションは、視聴者に広告だと思われてスキップされます。
- 読む順に表示します。 次の行が現れる前に、視聴者がその行を読み終えられるようにします。行(または節)ごとにタイミングをずらし、すべての単語を一度に表示したり、見栄えのために順序を入れ替えたりしないでください。
- 引用文はそのまま使います。 言い換えたり、文の途中を削ったり、評価をでっち上げたりしないでください。フレーズを強調する場合は、顧客自身が使った表現でなければなりません。
- 投稿者が証明になります。 誰が言ったのか分からない引用は、単なるスローガンです。名前+役職+会社名(実際のアバターがある場合はアバターも)は必須です。
引用カードの構成
| 要素 | 役割 | タイミング |
|---|---|---|
| 引用符のモチーフ | 言葉を読む前に「これは引用です」と伝えます | フレーム 0。最初に拡大/フェードインします |
| 引用文 | お客様の声を1行ずつ表示します | 間隔をずらし、約6~10フレームおきに表示します |
| 強調部分 | 購買意欲につながる1つのフレーズです | その行が落ち着いた後に表示します |
| 星評価 | 実際の評価に合わせて塗りつぶされたスコアです | 引用文の後に左から右へ塗りつぶします |
| 投稿者ブロック | 名前/役職/会社名/アバター | 最後に表示し、上にスライドします |
この順番で組み立て、同じ順番で表示します。視聴者は引用文を読み、信頼し、評価を見てから、誰の発言なのかを知ります。
行ごとにずらして表示
引用文を行(または節)に分割し、それぞれの表示タイミングをずらします。Remotion では、useCurrentFrame() に基づいて各行を動かし、決定論的にレンダリングします。フレームレンダラーと同期がずれる CSS トランジションや 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>
引用文ごとの強調は最大1か所にします。ハイライトが2つあれば、どちらも目立たなくなります。
星評価のアニメーション(端数を含む)
端数を含め、実際のスコアを表示します。星のグリフを1行分並べてマスクとして使い、塗りつぶしレイヤーを 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 — 引用ごとに1本の動画
メリットは、すべてのフィールドをプロパティにして、ハードコードは一切せず、レビューごとに1回レンダリングすることです。
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
色、フォント、引用符、レイアウトは1つのテーマオブジェクトにまとめ、50件の推薦コメントすべてでブランドの統一感を保ち、変更するのは文章と評価点だけにします。レビューのスキーマ、CSV→props の解析、引用文のタイポグラフィ(スマートクォート、ぶら下げ句読点、行分割、孤立行)、バッチスクリプトについては、references/batch-and-typography.md を参照してください。
出力チェックリスト
- 行は読む順序で表示します。登場時の動きは一貫させ、間隔は約6~10フレームにします。
- 引用文は一字一句そのままにし、強調する範囲は必ず1か所だけにします。その行が落ち着いてから強調を表示します。
- 引用文の後に、星を実際の評価点まで塗りつぶします(0.5刻みに対応)。正しい
aria-labelを設定します。 - 最後に著者ブロック(氏名+役職+会社名、実際のアバターまたはアバターなし)を表示し、そのまま静止させます。
- アニメーションする値はすべて
useCurrentFrame()から導出します。CSS/JS タイマーは使用しません。 - すべてのフィールドをプロパティにし、1つのテンプレートですべてのレビューをレンダリングします。
納品と検証(レンダリングした静止画 → 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を参照してください。
出力要件:
<Composition>として登録した Remotion のTestimonial(zod のschemaとdefaultPropsを含む)。すべての値をフレーム駆動にします(CSS トランジション/JS タイマー/Date.now()/Math.random()は使用しません)。- 納品物=レビューごと、アスペクト比ごとにレンダリングした
out/*.mp4(プロジェクトとレビューのデータも含め、新しい引用文でユーザーが再レンダリングできるようにします)。
検証ループ — 静止画をレンダリング → 確認 → エンコード。 まずは軽量な PNG を使います。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)
複数のアスペクト比/バッチ — リストをバッチレンダリングする前に、対象アスペクト比それぞれで1件のレビューを検証します。 レイアウトの不具合(引用文のはみ出し、著者の切れ)はレビュー × アスペクト比のすべてに繰り返し発生します。1回で見つけましょう。
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で引用文/星/著者を問題なくレンダリングできること。エラーやフォント/アバターの欠落がないこと。- 引用文は一字一句そのままで、強調する範囲が1か所だけであること。星は実際の評価点まで塗りつぶされていること。氏名/役職/会社名が正確で、安全領域内(9:16 の下3分の1にかからない位置)にあること。
- フレーム駆動のみであること。CSS/JS タイマー、
Date.now()、Math.random()を使用していないこと。 - 同梱するレビューのプロパティが正しくレンダリングされること(
defaultPropsだけではないこと)。aria-labelに実際の評価が設定されていること。 - バッチ処理の前に、9:16 + 1:1 + 16:9 で1件のレビューを検証すること。MP4 が再生できること。(任意)README 用に GIF を作成すること。
参考ファイル
references/quote-card.md— 実行可能な RemotionTestimonialコンポジション一式。行を段階的に表示する演出、キーフレーズのハイライト、端数に対応する星の塗りつぶし、著者ブロック、テーマオブジェクト、9:16 カードのタイミングマップを含みます。依存関係なしで使える HTML/CSS 版もあります。references/batch-and-typography.md— レビューのプロパティスキーマ、CSV/JSON→props の解析と検証、引用文のタイポグラフィ(スマートクォート、ぶら下げ引用符、行/節の分割、孤立行の制御、アニメーション中の読みやすさ)、星評価のアクセシビリティ、N 本の動画を作成する template×reviews のバッチレンダリングスクリプト。