映画風科学解説短編 · 統一制作仕様 v1
出典:『人類簡史 · 宇宙的自画像』(4K / 4'58" / 14場)および『向下 · DESCENT』(2K / 1'30" / 90秒 垂直断面図)。 両作品の仕様、ワークフロー、スタイル、そして踏んだ罠のすべてをここに収めています。新作はまず第0、1章を読み、その後今回関連する章を読んでください。
0. 鉄則(一つでも破るとやり直し)
- 音声を先に決め、映像を後で決める。ナレーションを一文ずつ生成 → 尺を計測 → 尺から各シーンのフレーム数を逆算する。決して映像を先に組んでから音声を合わせない。
- ナレーションとデータは一致させること:映像内に出てくる数字、単位、桁数は、事実表と一つ一つ照合する。ナレーションで98と言ったら、映像に90と書いてはいけない。単位の間違い(例:圧力の atm ↔ t/m²)は色合わせのミスよりはるかに重大。
- 一つのカットにつき一つの情報:各シーンでは、主要テーマ1つと最大3つの数値情報のみ許可する。それ以上の情報はナレーションに任せる。
- 文字は常に可読であること:全ての文字の下には必ず背景のベタ引きがあるか、暗くすること。階層名 ≥ 30px、数値 ≥ 13px。小さな文字の不透明度は0.6以上。
- ハードカット禁止:シーン間の切り替えは、ディゾルブ / 黒で一呼吸入れる / 連続した動きを用いる。同一作品内では一貫したトランジション手法のみを使用する。
- 無音レンダリング:Remotion内の
<Audio>は常に{false && ...}でオフにし、音声はffmpegで外部から合成する(長いWAVがあるとレンダリングがaudio preprocessingで止まる)。 - レンダリング前に必ず
npx tsc --noEmitを実行し、エラーがない状態にすること。さもないと、大量の不良フレームがレンダリングされ、やり直しになる。 - 納品前の3つのチェック:全体の長さの検証、最初と最後のフレームの検証、主要トランジションの1フレーム単位での検証(各箇所3~6フレーム)。
1. 標準パイプライン(順序通りに行うこと。飛ばし不可)
script.json ──► VO生成 ──► VO後処理 ──► 尺表 ──► タイムライン
│
└──► BGM(numpy)──► ミックス ──► master.m4a
映像(Remotion)──► 無音レンダリング ──► ffmpeg mux ──► 納品
1.1 脚本
- 1作品につき1ファイル:
script.json、フィールドはid / act / text / caption。 - 中国語ナレーションの場合、約 4.2 文字/秒。60秒の作品で約200~230文字、90秒で約300~340文字。
- 数字は中国語の読み方で書く(「三千六百八十八」)。そうしないとTTSが間違えて読む。映像内ではアラビア数字を使う。
1.2 ナレーション(Qwen3-TTS VoiceDesign、男性ドキュメンタリーボイス)
INSTRUCT = ("A deep, calm, authoritative male documentary narrator. Slow, deliberate, cinematic. "
"Low register, warm, intimate, restrained emotion, close-mic. Consistent, even pacing. Mandarin Chinese.")
generate_audio(text=..., model=model, lang_code="zh", instruct=INSTRUCT,
temperature=0.65, top_p=0.9, repetition_penalty=1.05,
output_path="vo_raw", file_prefix=id)
- モデルは
mlx-community/Qwen3-TTS-12Hz-1.7B-VoiceDesign-bf16、mx.random.seed(11)で固定。 - 各生成後、すぐに
ffprobeで尺をチェック:もしも1行が30秒を超えていたり、同じ文が繰り返されている部分があれば、TTSが劣化している証拠。削除して再生成する(seedを変更するか、repetition_penaltyを1.12に上げる)。 - ASRによる再チェック:
mlx_whisperで書き起こし、数字や難しい漢字(水素→清、ケイ素→龟、鉄→体 など)を確認する。
1.3 音声後処理(統一チェーン。各トラックで変えてはならない)
highpass=f=70,
asetrate=24000*0.912341, aresample=48000, atempo=1.096081, atempo=1.055,
equalizer=f=190:t=q:w=1.0:g=1.4, equalizer=f=3300:t=q:w=1.4:g=-1.8, equalizer=f=7200:t=q:w=1.8:g=-1.0,
acompressor=threshold=0.14:ratio=2.2:attack=10:release=200,
loudnorm=I=-20:TP=-3:LRA=7
さらに、20msのエネルギーエンベロープで先頭と末尾の無音部分をカットし、0.34秒を超えるポーズは0.34秒に圧縮。両端に12ms/50msのフェードイン/アウトを適用する。
1.4 タイムライン
frames = round(seconds * 24);ナレーションの開始オフセット = シーンの開始フレーム + lead(通常18~24フレーム)。- 各シーン:
lead + vo + tail、tailは16~90フレーム(最後のカットは余裕を持つ)。 timeline.tsを生成する(自動生成。手動で編集しない)。フィールドは{ id, from, dur, voAt, voDur }。
1.5 BGM(純粋なコード合成、numpy)
- 構造を持たせ、埋め尽くさない:タイムコードに沿って「イベント」を書く。パッド一本で通してはいけない。
- 和声:12~18秒ごとに変え、境界部分はクロスフェード。低音は55Hz以上の持続音のみ。
- 低音の轟音は避ける:視聴者は「ゴーゴーいう」「うるさい」と評する。低音は85~100Hzでカット。長音は純粋なサイン波を使用し、オクターブの倍音は加えない。
- 静けさ優先:BGMのレベルはナレーションの約 −20〜−27 dB。ナレーション中はさらに40~70%抑える(サイドチェイン・ダッキング)。
- 最終的なラウドネス:ドキュメンタリーとして −18〜−24 LUFS(−14ではない。それはストリーミング配信のポップス向け)。
- チュートリアル風の「効果音」(水中に潜る音、ソナー、金属の軋む音など)はクライアントから明確に要求された場合のみ追加する。一度却下されたことがあるため、デフォルトでは使用しない。
1.6 映像(Remotion)
第2章を参照。
1.7 レンダリングと合成
npx tsc --noEmit
npx remotion render Film4K out/silent.mp4 --codec=h264 --crf=18 --concurrency=7
ffmpeg -i out/silent.mp4 -i public/audio/master.m4a \
-map 0:v -map 1:a -c:v copy -c:a aac -b:a 320k -shortest -movflags +faststart out/final.mp4
- 4K = 1920×1080 レイアウト +
transform: scale(2);2K =scale(2560/1920)。レイアウトは1セットのみ記述する。 - 部分的な修正:該当フレーム範囲のみ再レンダリング →
ffmpegでtrim/concatして3つのセグメントを結合 →-c:v copyで音声トラックのみ差し替え。映像を変更する場合は3セグメントを再エンコードして結合する(約5~10分)。
2. ビジュアルシステム
2.1 ベースレイヤー
- キャンバス 1920×1080、24 fps。
AbsoluteFillの背景はほぼ黒(#01050A/#010407)。純粋な黒 #000 は絶対に使わない。 - 3層構造:背景グラデーション → ボリューメトリックライト/パーティクル → 情報レイヤー(テキスト、深度スケール、数値表示)。
- 統一された仕上げ:
Vignette+ 静的Grain(0.04、必ずanimate={false}を設定。動的ノイズは細線をチラつかせる)。
2.2 フォント
- タイトル/詩句:
Songti SC(セリフ体)、文字間隔 0.4~0.6em、大きなサイズ(90~250px)。 - データ/数値表示:
SF Mono、8~14px、文字間隔 0.16~0.36em。 - 説明文:
PingFang SC、14~19px、不透明度 0.55~0.7。
2.3 カラーパレット(各作品の「世界観を示す色」)
| 作品タイプ | 上部(明るい部分) | 中間部 | 下部(暗い部分) | アクセントカラー |
|---|---|---|---|---|
| 宇宙 / 時間 | #050506 背景 | クリーム #F3E7D0 | — | 琥珀 #E8B06A |
| 海 / 深度 | #1E7C93 水面 | #07232E | #01050A | シアン #4FE0C0 |
ルール:同一作品内ではアクセントカラーは1色のみ。生物発光や熱水などの例外は最大2色までとし、それぞれ特定の物理量に紐付ける。
2.4 パーティクルエンジン(Canvas 2D)
- 決定論的乱数(ハッシュ関数)。同じフレームでは常に同じ結果。クラウドタイプ:
ball / filament / disk / globe-surface / sphere-shell / figure / city / helix / neuron / glyph / single / text / timeline。 - 2回描画:最初に大きな半径で低い不透明度のグロー、次に小さな半径で高い不透明度のコア。
globalCompositeOperation = 'lighter'。 - 点群の境界は画面外に出すこと:
makeCloud('text', n)は3×1.2のボックスになる。投影すると矩形のエッジが現れる(視聴者から最も頻繁に指摘されるバグ)。expand(cloud, kx, ky, kz)で2.4~3.2倍に拡大する。
2.5 生物と地形(SVG)
- 全て横向き、頭を進行方向に向ける。目、ヒレ、口のライン、のどのヒダ、フジツボなどの解剖学的ディテールを少なくとも4箇所に配置。そうしないと貼り付けたように見える。
- シルエット + エッジライト(不透明度0.2~0.35)。身体に
feTurbulenceを重ねない(花崗岩のようになる)。 - 地形:複数セグメントのポリライン + 地層線 + 砕屑物 + 堆積物。三角形は使わない。山のベースラインは描かない(グラフのようになる)。
- 生物の出現ウィンドウは「深度/時間」に基づいて設定し、一度に3種以上出現させない。
2.6 情報レイヤー(HUD)
- 階層帯のネームプレート:暗いグラデーション背景(0.72→0)+ 左側2pxのアクセントカラー縦線 + 中国語 30~35px の純白テキスト。
- 数値表示:階層あたり2~3グループ。
LABEL8.5px /VALUE13~14.5px。 - スケールバー:目盛り線 + 現在値を太字表示。現在値はリアルタイムで計算すること、ハードコードしない(ハードコードするとインジケーターと矛盾する)。
- 全ての数字は単位付き。単位はスペースで区切る(
1,093 atm)。
2.7 トランジション
- 第一選択は連続した動き(ワンカメラ、ワンカット風):深度/時間は連続量であり、コンテンツはそれに伴って画面の出入りを行う。
- 第二選択は短いディゾルブ(4~6フレーム。新しいカットだけがフェードインし、古いカットは不透明なまま重なる)。輝度が落ちず、HUDのテキストも重ならない。
- 禁止:斜め方向のスイープ、長いクロスディゾルブ、垂直方向のプッシュ(暗いエッジが露出する)、黒フェード後のハードカット(「水中への潜入」などの物理的動機がある場合を除く)。
3. 事実とデータ
facts.mdを作成する。各項目は数字 / 単位 / 出典範囲 / 映像内での表記。- 最も間違いやすい3箇所:① 単位換算(1 atm ≈ 10.3 t/m² ≈ 1.03 kgf/cm²);② 「平均」と「極値」の混同(平均 3,688 m vs 最深 10,935 m);③ 簡略化した表現(90種類 vs 98種類の元素)。
- 作品全体で一貫した精度バージョンを使用する。ナレーションと映像は同じ出典に基づくこと。
4. 納品物リスト
deliverables/
作品名-4K-ナレーション版.mp4 # メインバージョン
作品名-4K-音楽のみ版.mp4 # 必要な場合
ポスター-4K.png / プレビュー-4K.png # キーフレームの合成
カバー/ # 1920 PNG + 4K PNG + 1146×717 JPG
ディレクターズノート.md # 構成、音声、修正履歴
公開用コピー-Bilibili.md # タイトル/概要/タグ/固定コメント/カバー案
事実表.md
公開パッケージには必ず含めるもの:AI生成に関する声明、制作クレジット(モデルが何をしたか、人間が何をしたか)、「間違えやすい数字」をまとめた固定コメント。
5. トラブルシューティング(発生頻度順)
| 現象 | 根本原因 | 修正方法 |
|---|---|---|
| レンダリングがaudio preprocessingで止まる | 長いWAV + <Audio> | 無音レンダリング、外部mux |
| パーティクル上で文字がぼやける | 背景のベタ引きなし + 不透明度0.4~0.5 | 背景のベタ引き + 純白 + フォントサイズ拡大 |
| 規則的な矩形が画面に現れる(視聴者が最も質問する) | 点群のボックスエッジが画面内に入る | expand() で2.4~3.2倍に拡大 |
| 細線/山のちらつき | 動的なフィルムグレイン | Grain animate={false} |
| クジラ/魚が「逆さまに泳ぐ」 | 頭と尾が逆、目が尾側にある | 横向きに再構築:頭を+x方向に |
| 山がグラフのようになる | パスで L ... Z を使い水平ベースラインを閉じた | 底辺を画面外に沈める |
| トランジションで視線が途切れる | スイープ/長いクロスディゾルブ | 短いディゾルブまたは連続した動き |
| BGMが「ゴーゴー」いう | 27~80 Hzの持続低音 | 85~100 Hzのハイパス、サブドローンを除去 |
| 音と映像が同期しない | 映像のビートとナレーションの内容が一致しない | 深度/時間曲線をナレーションの内容に合わせて再配置 |
| TTSが1行600秒になる | モデルの劣化ループ | 削除して再生成、repetition_penalty 1.12 |
| 4Kの修正が遅すぎる | 全編再レンダリング | 変更したフレーム範囲のみレンダリング + concat |
6. 2つの参考作品の場所
- 『人類簡史 · 宇宙的自画像』:
~/dsh-video-remotion/film/src/scenes/*、14場、4K、4'58"。 - 『向下 · DESCENT』:
~/dsh-video-remotion/film/src/ocean/*、6層帯、2K、1'30"。ナレーションとBGMは~/dsh-video-remotion/ocean/。 - 両作品とも
src/engine/particles.tsx(パーティクル)、src/engine/atmos.tsx(Vignette/Grain)、src/theme.ts(フォント/カラーパレット/イージング)を共有。