ナレーション → コードで描かれた2Dアニメーション作品(Short Film)
あなたはスライドショーではなく、ショートフィルムを作っています。ナレーションは固定されています。あなたの仕事は、見ている人がその瞬間に「見る」ものを考え出し、それをコードで描き、カットと視覚的なビートが正しい単語に合ったMP4を提供することです。
パイプライン全体は決定論的です。各シーンは時間の純粋関数であるため、どのフレームも単独でレンダリングできます。この性質により、インスタントなスチルレビュー、並列レンダリング、完全な音声同期が可能になります。
マシンに必要なもの
開始前にこれらを確認してください。これらが唯一の可動部分です。
python -c "import faster_whisper, playwright, PIL; print('ok')"
ffmpeg -version
不足している場合: pip install faster-whisper playwright pillow、その後 python -m playwright install chromium。ffmpegはPATHに含まれている必要があります。何かがインストールできない場合は、ユーザーに不足しているものを伝え、より弱い方法に切り替えないでください。
ワークフロー
ユーザーの視点をシンプルに保ちましょう。ユーザーは音声を提供し、動画を望んでいます。以下の手順を順に実行し、可視化されたタスクリストを維持してください。
1. まずは聞く:単語のタイミング
python <skill>/scripts/transcribe.py voiceover.mp3 work
これにより、文とその開始/終了時刻、およびすべての単語が word@start 形式で出力され、work/words.json に保存されます。以降のすべての処理は、これらの数値に基づいて計画されます。合計時間をメモしてください。
2. 音声の隣にプロジェクトをセットアップ
<skill>/assets/template/ を作業フォルダにコピーし、以下のようになるようにします。
voiceover.mp3
render.py
src/index.html src/engine.js src/scenes.js src/main.js
src/engine.js を一度読んで(短いです)、references/engine-api.md をざっと見て、すでに何があるかを把握してください:イージング、シード付き乱数、カメラ、部分描画パス、そして版画風のモチーフ(雲、雨、稲妻、煙、スカイライン)などです。
3. アートの方向性を決め、それから単語に合わせてストーリーボードを作成
1つのビジュアル言語を選び、フィルム全体でそれを守りましょう:小さなパレット(5〜6色)、エッジとテクスチャの扱い方、人物の描き方。テンプレートには、リノカット/版画風のルック(骨のような紙、ネイビーブルーのインク、バーミリオン、ゴールド、手で切ったような揺れるエッジ)が同梱されています。それを使うか、scenes.js のパレットと POST スイッチを変更してスタイルを変更しても構いませんが、シーン間でスタイルを混在させないでください。バラエティは、各シーンでどの色が支配的か(夜のシーン、紙のシーン、赤のシーン)によって生まれ、ルールを変えることではありません。
次に、コードを書く前にストーリーボードを作成します:各ショットの絶対的な開始/終了時間、各ショットがカバーする単語、画面に表示されるもの、各ビートが着地する正確な単語のテーブルです。references/storyboarding.md を読んで、ナレーションを画像に変換する方法を学んでください。これがフィルムの良し悪しを決める部分です。
簡略版:
- フレーズごとに1つのアイデア。3つの節を含む文は、通常、3つのショット、または1つのショット内の3つのビートになります。
- 物事を表示し、キャプションを付けないでください。ナレーションを繰り返す画面上のテキストは、視聴者に見る代わりに読ませてしまいます。デフォルトではテキストは一切表示せず、名前、実際のデータ、チャート上の短い中立的なラベルのみ例外とします。ユーザーがテキストの好みを明示している場合は、それが優先されます。
- フィルムに背骨を与えましょう:繰り返し登場するキャラクターやモチーフ、そして冒頭の何かを最後にコールバックする要素です。
- 意図的にスケールとカメラを変えましょう:ワイド、クローズアップ、図解、地図、断面図。連続する2つのショットが同じ構図であってはなりません。
- ナレーションがオチで終わる場合は、最後の単語の後に1〜2秒の無音のテールを追加して、最終的な画像が着地できるようにしてください。
render.pyが音声をパディングします。
4. 残りを書く前に、1つのシーンを完全に作り上げる
最初のショットを src/scenes.js に書き、SHOTS に登録して、確認します:
python render.py stills 0.3,1.5,2.9 first
次に、Readツールで work/first.png を開きます。これを他のシーンをコーディングする前に行ってください。これによりパイプラインが機能することが証明され、さらに重要なことに、スタイルをまだ簡単に変更できるうちに評価できます。
5. 残りのシーンを、少しずつ書く
システムを機能させ続けるルール(それぞれが、破ると特定の障害を引き起こすために存在します):
- 時間の純粋関数。 ショットは
function name(g, t, u)であり、tは絶対秒数、uはショットが始まってからの秒数です。フレーム間で蓄積される変数、Math.random()、Dateは使用しないでください。hash(n)、noise1(x)、rng(seed)を使用してください。フレームは複数のブラウザによって順不同でレンダリングされます。状態を持つものはすべて、ちらつきや一致しないチャンクとして現れます。 - 絶対時間でアニメーションする。
E.out(seg(t, 12.62, 13.1))のように、単語リストの数値をそのまま使って記述します。編集が変更されても、ビートはその単語に留まります。 - すべてが少し動く。 静止したフレームはバグのように見えます。すべてのショットに遅いカメラドリフト(
1 + u * .01のズームで十分)と、いくつかの二次的な動き(雨、煙、揺れる物体)を与えてください。 - すべてにイージングをかける。 到着するものには
E.out、カメラ移動にはE.inOut、ポップアップにはE.back、着地にはE.bounce。線形の動きは機械的に見えます。 - 世界をフレームより大きく描く カメラがズームアウトしたり、揺れたりするときは、背景と地面を0..1920よりはるかに超えて塗りつぶし、どの端も露出しないようにします。
- 衝撃には3つの要素:2〜3フレームの全画面
flash、減衰するshake、そして反応する何か(パフ、反動、色の反転)。 - シーンコードをファイルに分割する(
s1.js、s2.js、...)、ファイルが数百行を超えた場合、そしてそれらをscenes.jsの前にindex.htmlに追加します。
2、3のショットを書き、それらのコンタクトシートをレンダリングし、見て、修正し、続けます。フィルム全体を目隠しで書かないでください。
6. スチルでレビューする - これがあなたの目です
あなたはビデオを見ることができないため、コンタクトシートがレビュー手段です。すべてのショットについて、少なくとも開始、メインアクションの途中、終了、そして各ビートの正確なフレームをサンプリングします:
python render.py stills 12.2,13.3,14.3,15.4,16.5 act2 # シートあたり最大約16のタイムスタンプ
python render.py sheet 4 # フィルム全体、4秒ごとに1フレーム
PNGを読み、ショットごとに確認します:被写体は一目でわかる十分な大きさですか?何かがクリップされたり、重なったり、浮いたりしていませんか?重要なものは背後にあるものとコントラストがありますか?デザインされたように見えますか、それともフレームの半分が空ですか?修正し、同じタイムスタンプを再レンダリングします。references/pitfalls.md には、犯しやすく、気づきにくいミスのリストがあります。
ページエラーは render.py によって PAGE ERROR: 行として出力されます。黒または半分しか描画されていないフレームは、通常、そのショットでの例外を示しています。
7. レンダリングと検証
python render.py full --workers 8
バックグラウンドで実行します。70秒のフィルムは約2,100フレームで、数分かかります。output.mp4(1920x1080、H.264 + AAC、音声は全長にパディング)が書き出されます。次に、スチルだけでなくファイル自体を検証します:
ffprobe -v error -show_entries format=duration:stream=codec_name,width,height -of default=nw=1 output.mp4
python render.py sheet 6
再生時間、オーディオストリームがあること、概要シートに空のフレームがないことを確認します。レポートでは、スチルとファイルプロパティを確認したが、動いている状態では見ていないことを明確に述べてください。ユーザーは一度自分で視聴する必要があります。
8. 引き渡し
ユーザーに output.mp4 のパス、概要シート、および編集後に再レンダリングする方法についての1行を提供します。src/index.html をブラウザで開くと、音声付きのライブプレーヤーが表示され、これがユーザーにとってタイミングを確認する最も速い方法です。
サウンド
ユーザーが音楽や効果音を要求しない限り、ナレーションのみを提供します。要求された場合は、最終的なmuxで追加のffmpeg入力として追加し、ビジュアルに使用したのと同じビートリストからタイミングを取ります。
参考ファイル
references/storyboarding.md- ナレーションをショットに変換する方法;ビートの配置;視覚的なメタファー;シーンをデザインされたものに見せる要素。ステップ3の前に読んでください。references/engine-api.md-engine.js内のすべてのヘルパーとその1行での使い方。ステップ5の前に読んでください。references/pitfalls.md- 苦労して見つかった失敗モードとその修正方法。ステップ6の前に読んでください。references/example-bells/- 完全な71秒のフィルム(16ショット、約900行のシーンコード)とそのストーリーボード。storyboard.mdを読んで期待される計画レベルを確認し、特定のエフェクト(登るキャラクターを追うカメラ、爆発、地図、線を描く羽ペン、細くなる目)がどのように構築されたかを知りたいときにsrc/s*.jsファイルを開いてください。