Remotion トピック解説動画スキル(50~60秒)
このスキルは、任意のトピックについて、高品質な50~60秒のショートフォーム解説動画(TikTok / YouTube Shorts / Reels形式:1080×1920 @ 30fps)を作成するためのガイドです。
以下の要素を組み合わせています。
- 視覚的なベストプラクティス(
remotion-dev/skillsより:フレーム精度のスプリング、クランプ補間、シーケンス構成、タイポグラフィ階層) - AI音声合成(
.envのTTS_PROVIDER経由):edge(edge-tts-universal、オンライン、無料)またはcit(CIT Voice Studio、オフラインのベトナム語スタジオ音声 - github.com/quyen2867/cit-voice-studioでダウンロード、APIドキュメント:docs/cit-voice-studio.md) - 正確な時間同期:音声の長さを直接Remotionのフレームシーケンスにマッピングします。
1. 動画構成とタイミング(50~60秒 / 1500~1800フレーム @ 30fps)
魅力的なショート動画は、フック(Hook)-問題(Problem)-解決策(Solution)-価値(Value)-アウトロ(Outro) のフレームワークに従います。
| シーン | 名称 | 時間 | フレーム範囲(@ 30fps) | 目的とビジュアル |
|---|---|---|---|---|
| 1 | フック | 0秒~5秒 | ~150フレーム | 即座に注目を集める:大きなタイトル、好奇心を刺激する質問、フローティングバッジ |
| 2 | コンテキスト / ペインポイント | 5秒~15秒 | ~300フレーム | 問題や、このトピックが重要な理由の背景を示す。警告アイコン/比較 |
| 3 | コアコンセプト パート1 | 15秒~28秒 | ~390フレーム | コアとなる原理1を説明:ガラスカード、図解アイコン、強調キーワード |
| 4 | コアコンセプト パート2 | 28秒~42秒 | ~420フレーム | 詳細または動作メカニズムを拡張:3ステッププロセス、スムーズなフロー図 |
| 5 | 実世界への影響 | 42秒~52秒 | ~300フレーム | 実用的な応用、実践的なアドバイス、または印象的なデータ |
| 6 | アウトロ & CTA | 52秒~60秒 | ~240フレーム | 心に残る一言、Like/Share/Followの呼びかけ、個人ブランディング |
合計時間: 1500~1800フレーム(約50~60秒)
2. TTS音声生成(edge | cit)
2.1 .envによる音声設定
.envファイルが設定されていることを確認してください(詳細は.env.exampleを参照):
TTS_PROVIDER=edge # edge | cit
TTS_OUTPUT_DIR=public/audio
# Edge TTS(TTS_PROVIDER=edge)
EDGE_TTS_VOICE=vi-VN-HoaiMyNeural # または vi-VN-NamMinhNeural、en-US-ChristopherNeural
EDGE_TTS_RATE=+10% # +10% から +15% でショート動画のテンポを速く魅力的に
# CIT Voice Studio(TTS_PROVIDER=cit)
CIT_TTS_BASE_URL=http://127.0.0.1:8001
CIT_TTS_VOICE=Hải Đăng # 音声一覧:docs/cit-voice-studio.md または GET /voices
CIT_TTS_SPEED=1.1 # 0.5 - 2.0
TTS_PROVIDER=citの場合:
- CIT Voice Studioアプリが起動している必要があります。スクリプトは自動的に
GET /healthを呼び出してから音声を生成します。接続できない場合は、アプリを開くようにユーザーに促します(またはgithub.com/quyen2867/cit-voice-studioからダウンロード)。 - 台本には感情タグ
[cười](笑い)、[thở dài](ため息)、[hắng giọng](咳払い)と休止タグ[nghỉ 0.5s](0.5秒休止)を挿入できます(これらは読み上げられません)。乱用は避けてください:1シーン最大1タグ。 - エラー
400 Voice not found=音声名が間違っています(アクセント記号が区別される)。CIT_TTS_VOICEを確認してください。
2.2 音声ファイル生成手順
トピックを受け取ったら、音声台本ファイルを作成し、scripts/generate-tts.tsスクリプトを実行して音声を生成します:
import { generateTopicVoices } from "../../scripts/generate-tts";
const scenes = [
{
id: "scene1_hook",
text: "Dockerとは実際何で、なぜすべてのプログラマーに必要なのかご存知ですか?",
},
{
id: "scene2_problem",
text: "以前は、「私のマシンでは動く」という言葉が、製品を引き渡す際の悪夢でした。",
},
{
id: "scene3_concept1",
text: "DockerはこれをContainerで解決します。コードと環境全体を一つの塊にパッケージ化します。",
},
{
id: "scene4_concept2",
text: "重い仮想マシンとは異なり、DockerはOSカーネルを共有するため、瞬時に起動します。",
},
{
id: "scene5_impact",
text: "これにより、AWS、GCPから低価格VPSまで、あらゆるサーバーにアプリケーションをシームレスにデプロイできます。",
},
{
id: "scene6_outro",
text: "チャンネルをフォローして、毎日短くまとめたテクノロジー知識を手に入れてください!",
},
];
await generateTopicVoices("DockerShort", scenes);
音声ファイルは自動的にpublic/audio/<TopicName>/<sceneId>.<ext>(edgeの場合は.mp3、citの場合は.wav)に保存され、各シーンの正確なフレーム数(durationInFrames)とaudioPathを記録したmanifest.jsonファイルも生成されます。
- オプション:各シーンに
voice(選択したプロバイダーの音声)、rate/pitch/volume(edgeのみ)、speed0.5-2.0(citのみ)を指定できます。 - 既存のファイルは再利用されます(キャッシュ)。台本を編集したり音声を変更した後に再生成するには、対応する音声ファイルを事前に削除してください。
3. Remotionコーディングルール(remotion-dev/skillsより)
Remotionのソースコードを記述する際は、以下のルールに必ず従ってください:
3.1 スプリングアニメーションの使用
CSSキーフレーム/トランジションやリニアイージングは使用しないでください。代わりにspring()を使用します:
import { spring, useCurrentFrame, useVideoConfig } from "remotion";
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
// Card/Icon用のスムーズなバウンススプリング
const scale = spring({
frame,
fps,
config: {
damping: 12, // 15未満で自然な弾力性のあるバウンスを生成
stiffness: 100, // 剛性
mass: 0.8,
},
});
const entrance = spring({
frame: frame - 10, // 10フレーム遅延
fps,
from: 50,
to: 0,
});
3.2 安全な補間(常にクランプ)
タイムラインが範囲外で実行された場合の値のオーバーフローを防ぐため、常にextrapolateLeft: "clamp"とextrapolateRight: "clamp"を指定します:
import { interpolate } from "remotion";
const opacity = interpolate(frame, [0, 15], [0, 1], {
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
});
3.3 オーディオの埋め込みとシーケンスの同期
Composition内の各シーンでは、<Sequence>または<Series>を使用してタイミングを正確に管理します:
import { Audio, staticFile, Sequence } from "remotion";
// Sceneコンポーネント内 - manifestからパスを取得し、拡張子.mp3をハードコードしない(citプロバイダーは.wavを出力):
<Sequence from={0} durationInFrames={sceneDuration}>
<Audio src={staticFile(audioManifest.scenes[0].audioPath)} />
<SceneContent />
</Sequence>
- スナッピーなトランジションバッファ:
- シーン間のバッファは、ナレーション終了後**+3~+4フレーム**(約0.1秒)のみにします。
- バッファが長すぎる(+15~+20フレーム)と、シーン間に無音/テンポの乱れが生じるため避けてください。次のシーンは、前の文が終わった直後に表示され、短尺動画のテンポを維持する必要があります。
// Series 内の各シーン時間の計算例
const d1 = audioManifest.scenes[0].durationInFrames + 3;
const d2 = audioManifest.scenes[1].durationInFrames + 3;
// ...
3.4 ビジュアルデザイン標準(縦型1080x1920)
- 背景:高級感のあるダークモード(
bg-slate-950またはグラデーションfrom-slate-950 via-zinc-900 to-black)に、ラジアルグロー/グリッドの淡いエフェクトを組み合わせます。 - グラスモーフィズムカード:
backdrop-blur-xl bg-white/10 border border-white/20 rounded-3xl p-8 shadow-2xl
- 上部チャンネルブランド(Brand Header):
- ブランドコンポーネント
⚡ [CHANNEL_NAME]を常に上部中央(top: 150px、left: 50%translate-x)に表示します。値は環境変数CHANNEL_NAME(デフォルト:"mquyen")から読み取り、プラットフォーム(TikTok、Shorts、Reels)の検索バーや「フォロー中」「おすすめ」タブで隠れないようにします。
- ブランドコンポーネント
- モバイル最適化されたタイポグラフィ(1080x1920):
- メインタイトル:72px~96px、太字 font-black、シャープなグラデーション。
- カード/引用コンテンツ:40px~50px、font-extrabold。
- サブテキスト/説明:28px~36px、font-semibold。
- カテゴリバッジ:28px~32px、font-black、大文字。
- 中央レイアウトと1行チャンクキャプション:
- メインレイアウト:重要なコンテンツブロック全体は、画面の中央(垂直方向に
justify-center)に配置する必要があります。 - キャプションの位置:中央ブロックの下に十分な余白(
mt-64)を確保して配置し、TikTok/Reelsの下部ツールバーで隠れないようにします。 - 1行フォーマット:キャプションは1行のみ(約5~7単語) とし、大きなフォント
text-4xl font-blackで表示し、句読点で自動的に区切り、音声の進行に合わせてスムーズに切り替わります(durationInFrames)。キーワードを強調したピル型カードrounded-full bg-slate-950/95 border-2 border-sky-400/50 px-10 py-5を使用します。
- メインレイアウト:重要なコンテンツブロック全体は、画面の中央(垂直方向に
4. Antigravity / Codex向け動画作成のステップバイステップ手順
「[トピックX]についての解説動画を作成して」というリクエストを受け取った場合:
ステップ1:台本作成
- 6つのシーン(フック、問題、コンセプト1、コンセプト2、インパクト、アウトロ)を特定します。
- 自然で簡潔なベトナム語の台詞を書きます。各シーン15~30単語程度の短い文にします。
ステップ2:音声生成(TTS生成)
.envファイルのTTS_PROVIDERを読み取り、現在edgeとcitのどちらを使用しているかを確認します。- スクリプト
scripts/generate-<topic>-audio.tsを作成し、generateTopicVoicesを呼び出して、npx tsx scripts/generate-<topic>-audio.tsを実行します。 manifest.json/src/<TopicName>/audioData.tsから実際のフレーム時間のリストを取得します。
ステップ3:コードディレクトリsrc/<TopicName>/の作成
標準的なディレクトリ構造:
src/<TopicName>/
├── <TopicName>.tsx # メインのComposition、Series.Sequenceを集約
├── types.ts # スキーマとProps
├── audioData.ts # 音声時間のメタデータ
└── scenes/
├── Scene1Hook.tsx
├── Scene2Problem.tsx
├── Scene3Concept1.tsx
├── Scene4Concept2.tsx
├── Scene5Impact.tsx
└── Scene6Outro.tsx
ステップ4:src/Root.tsxへのComposition登録
新しいCompositionをsrc/Root.tsxに追加します:
<Composition
id="<TopicName>"
component={<TopicName>}
durationInFrames={totalFrames}
fps={30}
width={1080}
height={1920}
defaultProps={{}}
/>
ステップ5:確認と報告
npm run lintを実行してTypeScript/ESLintのエラーを確認します。- ユーザーに、Remotion StudioでCompositionを開くためのリンク(
http://localhost:3000)またはMP4レンダリングコマンドを報告します:npx remotion render <TopicName> out/<TopicName>.mp4