1仕組みと動作原理
手法全体が「1つのテンプレート × 1つのデータテーブル → 各行1本の動画」に基づいて構築されています。まず1行のレコードに対して型定義されたスキーマを策定し、動画全体をそのレコードの純粋関数とします。1行のデータで埋められないシーンはWrappedに配置すべきではありません。
Define a typed schema for one record. The whole video is a pure function of it.
2つ目の必須要件は「スクリーンショットを想定した設計」です。各シーンは2秒以内に読み取れ、静止画として停止させた状態でも美しく見える必要があります。なぜなら、実際にSNS等で共有されるのはその1枚の静止画だからです。
2. **Built to be screenshotted.** Each scene must read in under 2 seconds and look good frozen
シーン構成は5〜7種類の短いシーンタイプ(Intro / Big-number / Top-X / Superlative / Comparison / Time-heatmap / Outro)に固定され、各シーンは約2.5〜4秒です。年ごとにデータと配色のみを変更し、シーン構成自体は変更しません。
A Wrapped is a fixed sequence of short scene *types*, each ~2.5–4s.
ストーリー展開は「インパクトの上昇順」で構成します。統計指標を感情的な負荷(数値の大きさ、希少性、見栄えの良さ)の昇順に並べ、メインとなる数値をクライマックスに配置して最も長く表示します。後から盛り上げられなくなるため、最大の数値を最初に出してはなりません。
**Sequence stats for rising impact — smallest first, biggest last.**
主人公は必ず視聴者自身でなければなりません。最初の2秒以内に名前を表示し、ユーザー専用のアクセントカラーを採用し、コピーはすべて二人称を使用します。異なる2人のユーザーに対してある1フレームが全く同一に見える場合、そのフレームは機能していません。
If a frame would read identically for two different users, it isn't pulling its weight.
代表的なモーション演出は巨大な数値カウントです。必ずuseCurrentFrame + springで駆動させる必要があり(レンダラーのフレーム単位スナップショットでチラつきが発生するためsetState/setIntervalは禁止)、ロケール形式を適用し、数値変動時の幅の揺れを防ぐためにtabular-numsを使用します。
Drive it from `useCurrentFrame()` (never `setState`/`setInterval` — that flickers on render), ease it with a spring, and format with `toLocaleString()`.
縦型のセーフゾーンはピクセル単位で定量化されています。1080×1920でレンダリングし、重要コンテンツ(名前、数値、リスト、CTA)は画面高さの中央80%以内に収め、上下のプラットフォームUI被りエリア(上部12%、下部18%)を回避します。
Render **1080×1920**. Stories/Reels/TikTok crop and overlay UI, so keep all type and key numbers inside the **center 80% height**, clear of the **top 12%** and **bottom 18%**.
バッチレンダリングはこの手法の価値を具現化する部分です。1度バンドルした後、行ごとにselectComposition + renderMediaを実行してinputPropsを渡し、不変のIDで命名して冪等性を担保します。バリデーションに失敗した行はスキップしてログを記録し、中途半端な生成物をレンダリングしません。
The payoff. Render every data row to its own MP4 with `renderMedia`, passing the row as `inputProps`.
2コア機能
3外部依存関係
| Kind | Dependency / Endpoint |
|---|---|
| cli | npx remotion still / render / compositions(单行验证与正式编码) |
| cli | npx tsx(运行批量脚本 render-all.ts) |
| package | @remotion/bundler 与 @remotion/renderer(bundle + 逐行渲染) |
| package | zod(行级 schema 校验)、p-limit(并发上限)、csv-parse(CSV 解析)、@remotion/transitions(转场) |
| network | @remotion/google-fonts:批量渲染时把字体内联进 bundle(避免 headless 缺字形/FOUT) |
| api | 可选:Remotion Lambda(AWS 无服务器扇出),面向万级批量 |
| cli | ffmpeg / ffprobe(contact-sheet.sh 与 probe-mp4.sh) |
4推奨統制措置と判定根拠
- scripts/: ローカルスクリプトまたはコマンドの実行: npx remotion still / render / compositions(SKILL.mdの指示に基づく):必要に応じてnpmからRemotionを取得・実行
- 网络端点: 外部ネットワークアクセスの宣言: ビルドフェーズ:@remotion/google-fontsがフォントを取得してバンドル内にインライン化(ヘッドレス環境対策としてリファレンスで明示的に推奨)
- 本地工作目录: ファイルの読み書きと成果物の出力: out/wrapped-<recordId>.mp4(1行につき1本の動画、冪等性担保のため不変IDで命名)、out/wrapped-<recordId>.jpg(
5二重目の独立検証
- [ok] 外部依赖调用点复核(npx remotion / npx tsx / @remotion/* / zod / Lambda) — SKILL.md Verify loop 确有 `npx remotion still Wrapped out/f-start.png --frame=0 --props='{...one user...}'` 与 `npx tsx render-all.ts`;batch-pipeline 确有 `import { renderMedia, selectComposition } from "@remotion/renderer";`、`p-limit` 与 `renderMediaOnLambda`;remotion-recipes 确有 @remotion/google-fonts 与 @remotion/transitions 用法。全部落地,非推测。
- [ok] 是否隐含云端凭据需求 — 本地路径(renderMedia)不需要任何云端凭据;仅可选 Lambda 路径会引入 AWS 配置。SKILL.md/reference 中无 AWS key、无 access token 字面量,也无读取 env 的代码——故按「不读凭据」处理,但在 security.reason 与 verdict.risks 中标注了 Lambda 接入时的凭据/计费含义。
- [ok] 帧驱动纪律的内部一致性 — SKILL.md 输出契约与 remotion-recipes 开篇「The one rule that prevents broken renders」一致禁止 setState/setInterval/Date.now()/CSS @keyframes 计时;大数字组件示例也确实只用 useCurrentFrame + spring + interpolate。
- [ok] 数据契约与场景语法的耦合 — wrappedSchema 字段(name / year / minutesListened / topArtists / topGenre / percentile / accent)与场景类型表逐项对应(Intro 用 name+year、Big-number 用 minutesListened、Top-X 用 topArtists、Superlative/Comparison 用 percentile+topGenre、per-user accent 贯穿);未见场景需要而 schema 未提供的字段。
- [ok] 安全区数值与 storyboard 的自洽性 — 1080×1920 下 top 12% = 0–230px、bottom 18% = 1575–1920px、center 80% = ~230–1575px,与 scene-grammar 的安全区表一致;垂直中心 ~960px 落在中心区内。数值互相自洽。
- [ok] 跨目录 / 跨 skill 引用可解析性 — 正文引用的 `scripts/contact-sheet.sh`、`scripts/probe-mp4.sh` 位于仓库根(单装本 skill 目录会悬空,需装整个 repo);本 skill 自成闭环,未强依赖兄弟 skill(只需 Remotion 本体)。
- [ok] 功能声明 vs 实际能力 — frontmatter 宣称覆盖「数据行 → 一条可分享视频」的范式、场景语法、计数动效、9:16 取景与批量渲染,SKILL.md 与三份 reference 逐项兑现(含 CLI 与 Node 两套批量变体);未夸大——不声称自动产出数据或自动分发。
6結論
16427a3a8db59d32…