--- name: tiktok-promo-video description: >- promo-video/ 配下のRemotion動画プロジェクト専用。TikTok縦型プロモ動画のシーン作成・ 編集・レンダリングワークフローを提供する。promo-video/ 内のファイルを触る作業や、 Remotionコンポーネントの追加・修正で使うこと。 汎用的な動画編集やTikTok一般の質問には対応しない。 allowed-tools: Read, Grep, Glob, Edit, Write, Bash user-invocable: true --- # TikTok Promo Video (Remotion) PPT翻訳SaaSのTikTok縦型プロモ動画をRemotionで作成・編集するスキル。 ## When to Use This Skill - TikTokプロモ動画の新規シーン作成・既存シーン編集 - 動画の文言・タイミング・レイアウト修正 - 新しいComposition(A/Bバリアント)の追加 - コンポーネント追加・修正 - レンダリングとデバッグ ## Project Structure ``` promo-video/ ├── package.json # Remotion + React(バージョンはpackage.json参照) ├── tsconfig.json ├── public/screenshots/ # スクリーンショット素材 │ ├── upload.png │ ├── dashboard-empty.png │ └── landing.png └── src/ ├── index.ts # registerRoot(RemotionRoot) ├── Root.tsx # Composition登録(Folder + Composition) ├── constants.ts # 全定数: FPS, サイズ, シーン尺, カラー, コピー ├── fonts.ts # NotoSansJP (@remotion/google-fonts) ├── motion.ts # アニメーションユーティリティ ├── index.css # Tailwind (optional) ├── TikTokAd.tsx # Ad版メイン (Sequence) ├── TikTokPromo.tsx # LP版メイン (TransitionSeries) ├── components/ │ ├── Background.tsx # ダーク背景 │ ├── SafeArea.tsx # TikTok安全領域 (top:160, bottom:260) │ ├── KineticLine.tsx # テキスト表示(emphasis, veil対応) │ ├── Icons.tsx # SVGアイコン(Bolt, Shield, Table, Globe, Pen, Arrow) │ ├── TapRing.tsx # タップアニメーション │ ├── TimerBadge.tsx # タイマー表示 │ ├── ProgressBar.tsx # プログレスバー │ ├── GlowEffect.tsx # グロー演出 │ └── PhoneMockup.tsx # スマホモック └── scenes/ ├── HookScene.tsx # LP: フック(課題提示) ├── SolutionScene.tsx # LP: 証拠(タイマー + スクショ) ├── DemoScene.tsx # LP: 編集デモ(1行修正) ├── FeaturesScene.tsx # LP: 特徴カード(速い/表も翻訳/多言語/直せる) ├── CTAScene.tsx # LP: CTA(comment/try) ├── AdHookScene.tsx # Ad: Before/After カード ├── AdProofScene.tsx # Ad: タイマー + スクショ ├── AdDiffScene.tsx # Ad: 1行修正デモ └── AdCTAScene.tsx # Ad: CTA(profile/comment) ``` ## TikTok Format Constraints | 項目 | 値 | |------|-----| | 解像度 | 1080 x 1920 (9:16 縦型) | | FPS | 30 | | Safe Area上部 | 160px (UIオーバーレイ) | | Safe Area下部 | 260px (UIオーバーレイ) | | Safe Area左右 | 60px padding | | Ad版尺 | 11.5s = 345f | | LP版尺 | 15.0s = 450f | ## Composition Architecture ### Ad版 (TikTokAd) — `Sequence` ベース ``` Hook(24f/0.8s) → Proof(126f/4.2s) → Diff(105f/3.5s) → CTA(90f/3.0s) = 345f ``` - `Sequence` の `from` + `durationInFrames` で正確なフレーム制御 - `COPY_VARIANTS` (A/B/C) で文言A/Bテスト - `ctaVariant` ("profile" | "comment") でCTAモード切替 ### LP版 (TikTokPromo) — `TransitionSeries` ベース ``` Hook(29f) → Proof(107f) → Edit(143f) → Cards(128f) → CTA(75f) = 482f - 4*8f(transitions) = 450f ``` - `TransitionSeries` + `linearTiming` でシーン間トランジション - トランジション尺 = 8f (LP_TRANSITION) - **計算式**: 合計 = sum(シーン尺) - (トランジション数 * トランジション尺) ## Animation Rules (CRITICAL) ### 禁止事項 - **CSS transition/animation 禁止** — Remotionは各フレームを独立レンダリングするため動作しない - **emoji禁止** — クロスプラットフォームでレイアウトズレ。SVGアイコン (Icons.tsx) を使用 - **native `` 禁止** — `` + `staticFile()` を使用 ### 必須パターン ```typescript // アニメーションは必ず useCurrentFrame + interpolate/spring const frame = useCurrentFrame(); const opacity = interpolate(frame, [0, 10], [0, 1], { extrapolateLeft: "clamp", extrapolateRight: "clamp", }); ``` ### motion.ts ユーティリティ | 関数 | 用途 | 特徴 | |------|------|------| | `fadeIn(frame, start, duration)` | フェードイン | interpolate | | `fadeOut(frame, start, duration)` | フェードアウト | interpolate | | `enterFromBottom(frame, start, duration)` | 下から登場 | Easing.out(exp) | | `enterFromRight(frame, start, duration)` | 右から登場 | Easing.out(exp) | | `scaleIn(frame, fps, delay)` | スケールイン | spring(damping:200) — バウンスなし | | `springBounce(frame, fps, delay)` | バウンス | spring(damping:12, stiffness:200) | ## Component API Quick Reference 詳細は [components.md](components.md) を参照。 | コンポーネント | 主なProps | 用途 | |--------------|----------|------| | `SafeArea` | children | TikTok安全領域ラッパー | | `KineticLine` | text, fontSize, emphasisWord, veil | テキスト表示(固定幅、中央揃え) | | `Icons.*` | size | SVGアイコン (Bolt/Table/Globe/Pen/Arrow) | | `TapRing` | x, y, delay | タップ演出 | | `TimerBadge` | seconds, done | タイマー表示 | | `ProgressBar` | progress, done, width | 進捗バー | | `Background` | - | ダーク背景 | | `GlowEffect` | color, size, delay | グロー演出 | ## Workflow ### 新規シーン作成 1. `constants.ts` にシーン尺を定義 2. `scenes/` にシーンコンポーネントを作成 3. メインコンポーネント (TikTokAd/TikTokPromo) にシーンを追加 4. TransitionSeries使用時はフレーム計算を検証: `sum(scenes) - (transition_count * LP_TRANSITION) = LP_FRAMES` ### 文言変更 1. LP版: 各シーンファイル内のテキスト直接変更 2. Ad版: `constants.ts` の `COPY_VARIANTS` (A/B/C) を変更 ### レンダリング ```bash cd promo-video npx tsc --noEmit # 型チェック(必須) npm run render:all # 全4本レンダリング # 個別: npm run render:ad-profile # Ad Profile CTA npm run render:ad-comment # Ad Comment CTA npm run render:lp-comment # LP Comment CTA npm run render:lp-try # LP Try CTA ``` 出力先: `promo-video/out/` ## Common Pitfalls | 問題 | 原因 | 対処 | |------|------|------| | Folder name error | Folder nameにスペース | a-z, A-Z, 0-9, `-` のみ使用 | | NotoSansJP subset error | "japanese" subset指定 | 番号付きsubset `[0]`-`[123]` を使用 | | 循環参照 | Root.tsx ↔ Composition | fonts.ts を独立ファイルに分離済み | | render command format | `remotion render Root CompId` | `remotion render CompId --output path` | | 画像表示されない | native `` | `` | | フォントずれ | fontFamily未設定 | AbsoluteFill の style に `fontFamily` 設定 | | レイアウトずれ | 固定幅未設定 | KineticLine (maxWidth), テキストはcenter align | ## AI Assistant Instructions このスキルが有効化された時: 1. **promo-video/ で作業**: cd せず絶対パスを使用 2. **constants.ts を起点に**: 尺・カラー・コピーはすべてここ 3. **型チェック必須**: 変更後は `npx tsc --noEmit` を実行 4. **レンダリング確認**: `npm run render:all` で全本出力確認 5. **Remotion best practices skill も参照**: アニメーション・トランジション詳細 Always: - アニメーションは `useCurrentFrame` + `interpolate`/`spring` のみ - テキスト表示は `KineticLine` を優先使用 - アイコンは `Icons.tsx` のSVGアイコンを使用(emoji禁止) - 画像は `` を使用 - TransitionSeries のフレーム計算を検証する - SafeArea 内にコンテンツを配置する Never: - CSS transition/animation を使わない - emoji をテキストに含めない - native `` を使わない - フレーム計算を検証せずにコミットしない