ビデオ 100% コード (Remotion + ローカル音声)
作業順序 (順序は変えないこと)
- ストーリーを先に (HyperFrames
story.mdメソッド): 唯一のもの、3つのストーリーライン、最初の2秒にフック、パーセンテージ付きのビート、生成されたビデオの「テル」禁止 (すべてが均等に出入りする、理由なく浮遊する、カードが一列に並ぶ、ロゴが浮遊する)。SCRIPT.mdをタイムコード付きで作成。 - 音声 → 実際の長さ →
timeline.json(シーン、各行の開始、イベント、音楽セクション)。オーディオとビデオは同じJSONを読み取る。 - マスターオーディオ (音楽 + SFX + ダッキング付き音声、-15.5 LUFS、ピーク ≤ -1 dBTP)。
- シーンをRemotionで作成、1つの
Filmコンポジションに<Sequence>で各シーンを配置。レンダリング前にコンタクトシートでフレームを確認。 - シーンごとにレンダリング (
--frames=a-b --muted) → 結合 → ffmpegでmux → 抽出したフレームでQC。
エンジン
npx create-video@latest --yes --blank --no-tailwind <dir>;npx remotion add @remotion/transitions @remotion/media @remotion/effects @remotion/noise @remotion/paths @remotion/shapes @remotion/motion-blur @remotion/fonts。- GPUなしサンドボックス:
remotion.config.tsでConfig.setBrowserExecutable(<chrome-headless-shell>)、Config.setChromiumOpenGlRenderer("swangle")、setConcurrency(2)、setCrf(18)、setPixelFormat("yuv420p")。 - フォント:
@fontsource[-variable]/*パッケージ (npmは到達可能、Google Fontsは不可)。キャプチャ前にdocument.fonts.load()をdelayRenderで待つ (グリフ áéíóúñ¿¡)。 - Remotionのルール: すべて
useCurrentFrame()から派生;interpolateはclamp付き; Remotionのrandom(seed); CSStransition/animation、Math.random、Date、タイマー、useFrameは禁止。 - コスト測定 (2 CPU、1080p): 空シーン ≈0.1秒/フレーム; 2000スプライトキャンバス ≈0.7秒/フレーム; 全画面
filter: blur()≈2.5秒/フレーム。パーティクル: クローズドフォーム (位置 = f(seed, i, t))、事前ブラー済み放射状スプライト、globalCompositeOperation: "lighter"。 - 3分のショート (5400フレーム、1080×1920) は2CPUで約1時間30分。バンドルを保存 (
npx remotion bundle) してそこからレンダリング。
再利用可能キット (このリポジトリには含まれません。構築する部品のリストとして提供)
anim.ts (ロール別イージング、クローズドスプリング、keyedState、まばたき、ドリフト)、Camera2D.tsx (パララックス/ドリー付きレイヤー)、Particles.tsx (雨、蛍、塵、星、粒状ノイズ)、City.tsx (プロシージャルネオンシティ+反射)、Text.tsx (キネティック、ネオン、単語単位の字幕、可変タイトル)、Post.tsx (ビネット、フラッシュ、レターボックス、光線)、character/Mia.tsx (リグ: ポーズ+表情+ビゼーム A–H/X+まばたき+呼吸+リムライト+プロップ)、character/Lucero.tsx、Flat.tsx (手描き風揺らぎのある2Dワールド)、ChatScreen.tsx、lipsync.ts。tools/ のスクリプト: voice.py、make_voices.py、asr.py、make_timeline.py、make_audio.py、render_all.sh、assemble.sh、sheet.py。
キャラクター
- リグ = フレームごとにブレンド可能な数値パラメータ (ポーズ、表情、ビゼーム); 表情プリセット;
keyedStateによるトランジション (予備動作→アクション→セトル)。頭がガイド、体が追従; 2~5秒ごとにシード付きのまばたき; 決してすべてを同じカーブで同時に動かさない。 - リップシンク: Rhubarb
-r phonetic -f jsonをWAV 22kHzモノラル16bitに適用 → キュー A–H/X → キュー間で口のパラメータをブレンド (ブレンド50ms)。ささやき声では開口強度×0.7。 - アニメーション前にスチルとしてキャラクターシート (表情、ビゼーム、ポーズ) を確認。
音声 (スペイン語、ローカル)
- Kokoro-82M ONNX (
kokoro-onnx、音声ef_dora、em_alex、em_santa、言語es-419) およびPiper (piper-tts、es_MX-claude-high、es_AR-daniela-high)。モデルはGitHubリリースから (thewh1teagle/kokoro-onnx、k2-fsa/sherpa-onnx)。 - 子供:
rubberband -p N -Fで+4~+6半音 (フォルマント保持)。低音: -4。"多くの声から作られた声": -2stレイヤー (26%) + +0.3stレイヤーを12ms遅延 (18%) +大きなリバーブ。 - ASRで常に確認 (Parakeet-TDT 0.6B v3 via sherpa-onnx ≥ 2.0): テキストに対するWER; 5%超の場合は再生成またはフレーズを書き直す。エフェクト適用前に確認 (リバーブがASRの言語検出を混乱させる)。ASRの単語単位のタイムスタンプは字幕に使用。
- ユーザーが独自の音声を持っている場合 (例: ElevenLabs)、各行のWAVを置き換え、シーンに触れずにキュー/タイムラインを再生成。
音楽とSFX
pretty_midiでセクションごとにMIDIを構成 (bpm、進行、GM楽器) →fluidsynth -ni -g 0.6 -r 48000 -F out.wav MuseScore_General_Full.sf3 in.mid→ pedalboard (HPF、コンプレッサー、リバーブ) → pyloudnorm。- 視覚的な同期 = 同じビート演算 (1ビートあたりのフレーム数 = fps·60/bpm、各ビートをそのインデックスから計算)。
- 画面内に原因があるSFX; ピークを画像の1フレーム後に配置; テイクをローテーション; 存在しない効果音 (ブーン、雨、鉛筆、きらめき、サブインパクト) をnumpyで合成。
- ミキシング: 音声 -20 dBFS RMS、音楽は音声の下 -8 dB (ダッキング 120ms / 700ms)、SFX -4 dB、マスター -15.5 LUFS、ピーク 0.6。スペクトログラム (
ffmpeg showspectrumpic) でベッドノイズ (雨など) が音声を覆い隠していないか確認。
ディレクション (これまで読んだスキルから: Remotion、HyperFrames、iart-ai motion/kinetic/webgl、nolanx、anatomy、isometric-ops、taste-skill)
- ビートごとに1つの動き; 到着は長いテール (
bezier(0.16,1,0.3,1))、退出は40~50%短く; カメラはinOut; タイトルは着地後静止; 原因のある3~5種類のトランジション; 最も速いフレームでカット。 - パララックス: 背景 0.1~0.3倍、中景 0.5~0.7倍、前景 1~1.5倍 ブラー付き。ドローンプレーン = 対数目盛のネストされたプレーンのスタック (窓→ファサード→街区→地図→雲→惑星)。
- アイソメトリック: 単一投影; フラットシャドウ 15~30%; 上部ほど明るく。
- タイポグラフィ: 最大2ファミリー; タイトルは高さの4~9%; 文字のスタガー 20~40ms、単語 40~70ms; 可変フォントでウェイト/幅を調整。
- 縦型: 主要コンテンツは中央80%に; 字幕は安全な下部ゾーン (≥ 110px) に; テキスト ≥ 44px; 単語単位の字幕で音声なしでも理解できるように。