カートゥーン短編:アイデア → 脚本 → ナレーション → 完成MP4
見た目: 平たい2Dの豆ヘッドカートゥーンキャラクター(キャンバスに描かれた「カード」、プラム色の輪郭線)が、カラフルな3D世界の中で動きます。黒インクの輪郭線、ペイント風テクスチャ、被写界深度、滑らかなカメラワークが特徴です。出力は1080x1920、30fpsで、ナレーションの長さと正確に一致します。ユーザーの声はそのまま保持されます。BGMと効果音は合成され、音声レベルの50% で配置されます。実績あり:「決して去らなかった兵士」(19.7秒、8ショット)
ルール
- ストーリー、キャラクター、ショットは常にオリジナルであること。決して他のクリエイターの動画をショットごとに再現しないこと。代わりに、同じアイデアに対する独自の解釈を提供すること。
- 実在する有名人をキャラクターにしないこと。ブランドのマスコットやロゴも使用禁止。
- ユーザーが要求しない限り、キャプションは付けないこと。作中内のテキスト(刻まれたメッセージ、看板など)は可能です。ただし、正しく読めること(反転していないこと)。
- 音声を編集したり、タイミングを変更したりしないこと。映像は音声に合わせてタイミングが調整され、すべての視覚的なリアクションは、その単語が発声される0〜3フレーム前に配置されます。
- オーディオレベル: BGMは音声レベルの50%(−6dB、ゲートRMS)に設定します。効果音は50%以下に設定し、ピークがナレーションを超えないように制限します。ミキシングは常に
mix.pyを使用し、手動では行いません。この比率を変えるようなダッキングや圧縮は使用しないこと。ミックス全体には1つのリニアゲインとピークリミッターのみを適用します。 - タスクリストでユーザーに進捗を伝えること。長尺レンダリングの前にスチルコンタクトシートを送信すること。
ステージ1:受け付け(常に最初)
オーディオファイルが既に添付されている場合は、ステージ4にスキップします。脚本も渡されている場合は、それをタイミング調整に使用します。それ以外の場合は、1つのAskUserQuestion(またはそのツールがない場合はプレーンテキスト)を送信します:「どこから始めますか?」
- ナレーション準備完了:アップロードを依頼し、脚本テキストも持っていれば一緒にアップロードするよう依頼します(脚本があればタイミングが正確になります)。アップロードされたらステージ4に進みます。
- 脚本はあるがナレーションが必要:必要に応じてステージ3で脚本をブラッシュアップし、録音のヒントとともに返し、アップロードを依頼します。その後ステージ4に進みます。
- 動画のアイデアと脚本が必要:ステージ2に進みます。また、ユーザーが希望の長さを伝えていない場合は、それも尋ねます。デフォルトは20〜30秒です。45〜60秒も許可されます。
ステージ2:10個の動画アイデア
1つの返信で正確に10個のアイデアを番号付きで提示し、ユーザーに番号(または「もっと」)で返信するよう依頼します。各アイデアには以下を含めます:
- タイトル(5〜8単語、好奇心をそそるもの。例:「決して去らなかった兵士」)
- フックライン:最初に話される文で、事実として述べられる逆説(「ある男がエッフェル塔を売った。二度も。」)
- どんでん返し:1行で(動画を締めくくる皮肉な落ち)
- アニメーションに適している理由:2〜3の大きな視覚的瞬間(崩壊、暴露、追跡など)
- 真実か伝説か:それが文書化された歴史なのか、異論のある記述なのか、民間伝承なのかを明確に述べる。
このフォーマットに「完璧な」アイデアの条件:
- 物理的な因果関係があり、視覚的に示せる驚くべきストーリー。
- 明確な普通のキャラクター、エスカレートする賭け、そして最後の行でのどんでん返し。
- シンプルな3D形状とカートゥーンカード(町、橋、船、城、砂漠、研究所、宮殿)で構築できる設定。
- 10個のアイデアを時代とテーマにわたって混ぜること:古代、中世、1800年代、現代、科学、動物、発明、災害、奇妙な法律、幸運な偶然。
- 真実として提示するものについては、提供する前にWeb検索で重要な事実を確認すること。バイラルな伝説を事実として提示しないこと。ユーザーがどうしてもそれを望む場合は、「伝説によると」と枠組みすること。
- 実在する存命人物を冗談の対象にしないこと。過激な内容や政治的な内容は禁止。
ステージ3:脚本(アイデア選択後)
ナレーションのみを記述します(話されるテキスト内にト書きは含めません)。速度は約3.7単語/秒に調整:20秒 ≈ 75単語、30秒 ≈ 110単語、60秒 ≈ 220単語。構成:
- フック(文1、前置きなし):不条理な事実。
- 設定(1〜2行):いつ、どこで、誰が、具体的な詳細。
- エスカレーション(2〜4ビート、各ビートは前より大きい)。他者は疑ったり嘲笑ったりする。1つの誇張ジョークを使用。
- 謎またはピボット:「しかし、〜のとき...」/「実は、」で、本当の仕組みを導入し、しばしば日常的な例えを用いる。
- どんでん返し/決着:短く、皮肉的で、動画の最後の言葉。平易な話し言葉、短縮形、8〜15単語程度の文、数字は言葉で書く。視聴者が既に見ているものを説明しない。
その後、以下を返信します:
- コピー可能なブロック内の脚本。単語数と推定長さを含める。
- 1段落の視覚的計画(アニメーション化するショット)。
- 録音のヒント:安定した温かみのあるナレーターの声1つ。ElevenLabsが適しています(深みのあるナレーターの声、速度約1.05〜1.1、安定性約45〜55%)。Mp3またはwavで構いません。文の終わりで自然な間を残してください。音楽なしでエクスポートしてください。
- 依頼:「準備ができたらナレーションをアップロードしてください。完全な動画を作成します。」最終的な脚本テキストは保持します。ステージ4のタイミング調整に使用するため、音声認識は不要です。変更されたバージョンを録音した場合は、最終的なテキストを尋ねてください。
ステージ4:動画を制作する(ナレーションアップロード後)
ここからは中断せずにすべてを実行します。タイミングが解決できない場合にのみ質問してください。
4.0 キットを入手する
コードキットは このスキルフォルダ内の kit/ にあります(エンジン、ツール、実例、および同梱のthree.js r160とgithub.com/mromidev/claude-animated-shortsのtoon.ts Penライブラリ(両方ともMITライセンス))。フォルダを見つけるには find / -name SKILL.md -path "*cartoon-audio-short*" 2>/dev/null を実行し、その kit/ を読み取り専用として扱います。
次に bash <skill>/kit/tools/setup.sh ~/shorts/<slug> を実行します。これにより、エンジンとツールがプロジェクトにコピーされ、同梱のthree.jsがインストールされ、Node 22の module.stripTypeScriptTypes で toon.ts から型が削除され、Playwrightがリンクされます。ネットワークは不要です。同梱ファイルがない場合は、npmまたはgitクローンにフォールバックします。
- 要件:Node 22.6+、numpyとPillowを含むPython 3、ffmpeg、およびChromiumを使用したPlaywright(不足している場合は
npm i -g playwright && npx playwright install chromium)。 - パッケージレジストリがブロックされている場合、GitHub経由のgitが通常は機能します。TLSを無効にしたり、プロキシを回避したりしないでください。
- Chromium:事前インストールされたPlaywrightブラウザを
--use-angle=swiftshader --enable-unsafe-swiftshader --ignore-gpu-blocklistフラグとともに使用します。これにより、フレームあたり約3〜10秒でCPU WebGLが提供されます。
4.1 タイミング
python3 timing.py voice.mp3 script.txt --out work を実行します。
- whisperまたはfaster-whisperがインストールされている場合、単語のタイムスタンプを使用します。
- それ以外の場合は、スクリプトのフレーズ(句読点で分割)を無音検出された音声セグメントに整列させ、音節を継続時間に一致させ、セグメント内の文末とフレーズ内の長いギャップにペナルティを与えるDPを使用します。
- ASRもスクリプトもない場合は、スクリプトを要求します。Claudeは音声を聞くことができません。
work/phrases.jsonを確認します:ポーズは文末にくるようにします。総フレーム数 = round(duration × 30)。
4.2 ショット計画(コードの前の work/PLAN.md)
ショットごとに1行:フレーム、単語、設定、光、カメラの動き、キャラクター/ポーズ/表情、エフェクト、効果音のキュー。
- フレーム0は既にフック画像です。
- 通常、フレーズごとに1ショット。小さなフレーズは次のショットにマージします。
- すべての文を文字通りに図解します。小道具がジョークを運びます。
- ショットサイズを変える:フックMCU → ワイドリビール → ツーショット → キーオブジェクトのインサートクローズアップ → リアクションクローズアップ → 決着のための環境移動。
- ビートに光を使用:通常は昼光、衰退やドラマにはゴールデンアワー、説明には夜の青。時間の飛躍には6フレームの白いフラッシュ。
- どんでん返しのラインにはスティング(音楽停止、低いヒット、ロールを伴うプッシュイン)。最後のショットの物理的な決着は最後の単語で発生。
4.3 ワールド(web/main.js)
エンジンのセクションはそのまま保持:トゥーンマテリアル、インクコントラスト、add/tbox、空、ライト、カード、レンダーターゲット/ポスト、applyLight、drawActors、swapForNd、renderFrame。// ---------- world ---------- と // ---------- cards ---------- の間のサンプルワールド、および worldState() のストーリー部分を置き換えます。
- ペイントされたキャンバステクスチャ(
paint.js:板、梁、腐った木、石、苔/ツタ、草、土、漆喰、屋根瓦、大理石、バナー、刻まれたテキスト)を使用してプリミティブから構築します。同じフラットで暗い継ぎ目のスタイルで新しいペインターを作成します。 - 一定のテクセル密度、2ステップのトゥーングラデーション、およびフォグ = 地平線の色には
tboxを使用します。 - 背景:丘(半分埋まった球)、山(円錐 + 雪のキャップ)、ヒノキ/松の木、遠くの家、ペイントされた雲のビルボード。
- セットピース(崩壊、落下、ドア)は、
worldAt(f)からの0..1の進行によって駆動されるピボットグループであり、パーツはイーズアウトおよびスタガーされます。 - 曲線に沿った作中テキストにはプレーナUVを使用します。反転していないことを確認します。
4.4 キャスト(web/roman.js → web/toon.js)
romanFront(p, outfitKey, opts)は、ソールがy=975の600x1000のデザインキャンバスに描画します。カードの高さは2.25mなので、1単位 = 0.00225mです。- アウトフィットを
OUTFITS(チュニック/マント/鎧/兜/髪/帽子/あごひげ/エプロン/ドレス/トガ)に追加し、同じスタイルで新しい頭飾りや小道具を追加します。 - 腕のポーズ:垂らす、槍を持つ、指す、上げる、振る、腰に手、お腹、こめかみ(+渦巻き)、持ち上げる、手を伸ばす(+持ち上げる)、頬、盾、交差、親指。
- 表情:toon.tsのFACEセットに加えて、いびき、頑固、目を細める。必要に応じてFACEを拡張します。
- 編集後、
cat web/toonbase.js web/roman.js > web/toon.jsで再構築します。新しいデザインを使用する前に、キャラクターテストシートをレンダリングします。 - ビルボードはヨー方向のみ回転し、コンタクトブロブとアルファテストされたシャドウを取得し、ワールドパスでインク付けされることはありません。
q()で丸められた値からカードキーを構築します(これにより、キャンバスは目に見える変更があった場合のみ再描画されます)。- 分離されたパーツ(例:持ち上げられた兜)は独自のカードであり、
headCenter(seed)で整列されます:y = DECK + (partY − hc) × 0.00225。
4.5 モーション:スムーズで生き生きと(web/motion.js)
- カメラ:
camFromKeys(keys, f, {kicks})。スムーザーステップグライド(18〜45f)、リビールやホイップにはeaseOut、曲線的な動きにはpath経由点(Catmull-Rom)を使用します。すべてのホールドはわずかに動き、4フレーム以上静止することはありません。ドラマには3〜5°のロール、インパクトには7フレームのフリップシェイクを使用します。 - 連続性:連続的な動きを優先します(クローズアップからワイドへの引き、フォーカスラック、デッキを通ってのクレーン、オブジェクトへのプッシュ)。場所や時間のジャンプがある場合のみハードカットし、その場合はフラッシュを伴います。
- キャラクターは決して止まらない:すべてのカードに
idle(f, seed)を適用し、blinkAtで瞬きさせ、強調された単語で頭を上下に動かします。 - アクション:予備動作 →
backオーバーシュート →springセトル。スタンプは2フレームのディップ + ダストパフ + キックです。笑いは交互の傾き + 上下動です。 - 二次的な動き:バナーの布の波、葉/ほこり/水滴/Zzzエフェクトカード、流れる水。常に何かが動いています。
- 歩行:
walk()は距離 + 歩行フェーズを提供します。足は接地、上下動は3〜7%。 - レンズ:クローズアップとミディアムに被写界深度(cInf 8〜14 px)、目にピント。ワイドはシャープ。フォーカスラックは約14フレーム。
4.6 ルックチェック(フルレンダリング前)
各ショットの中間、トランジション、およびキーアクションでスチルをレンダリングします:node render.mjs stills/a "5,40,..." 次に python3 sheet.py stills/a stills/sheet_a.jpg を実行します。シートを見て、以下のトラップを修正します:
- 狭い垂直フレーム:水平方向の半幅 = d·tan(hfov/2)、hfov = 2·atan(tan(vfov/2)·0.5625)。4m、fov 40の場合、±0.8mなので、キャラクターを奥行き方向に配置します。
- 顔の前の手すりや柱(カメラが手すりの内側または約2.5m上にある)。家、屋根、茂みを通るカメラパス。約2m未満の前景小道具。柱の後ろに隠れたヒーロー。
- 反転したテキスト。分離されたパーツカードが間違った方向にオフセットされている。
- 押し出しマテリアルグループ:0 = キャップ、1 = サイズ+トップ。
- インクの欠落:エッジのみの出力をデバッグ。インク半径は1080で約2.5px。空は遠深度としてカウントされ、カードとしてはカウントされません。シートを1行のショットサマリーとともにユーザーに送信し、フルレンダリングを開始します。
4.7 サウンド(audio.py → ステム → mix.py)
ストーリーに合わせてキューテーブルを書き換えます。シンセサイザーはそのままです。audio.py はステム(music.wav、sfx.wav)のみを書き出します。
- 音楽:短い行進曲風のループ(キック/スネア、プラックベース、ブラスパッド)。どんでん返しのラインで停止し、その後は低いドローンが続きます。
- 効果音:イベント時(フレーム/30):大きな動きにはスウッシュ、スタンプにはドスン、崩壊にはゴロゴロ+クラッシュ、金属には擦る音、リビールにはティン、どんでん返しにはスティング、きしみ、パチン、水しぶき、いびき、葉、水のアンビエンス。
- ミキシング:
python3 mix.py voice.mp3 music.wav sfx.wavを実行。音楽を音声のゲートRMSの50%(−6dB)に正確に設定し、効果音を50%に、ピークは音声ピークの0.7倍に制限します。測定されたレベルを出力します:音楽が音声に対して−6.0dBであり、効果音がそれ以下であることを確認します。 - サウンドを作成する前にピクチャータイミングを固定します。タイミングを変更するたびに、audio.pyとmix.pyを再実行する必要があります。
4.8 レンダリング + 仕上げ
node render.mjs frames "0-<N-1>"をBashのrun_in_backgroundで実行し、進捗を報告してエラーやプロセス終了をキャッチするMonitorループで監視します。RESUME=1で中断後も続行できます。小型マシンでは同時に重いPythonを実行しないでください。bash finish.sh "Title"を実行します。約−14 LUFSの1つのリニアゲインと−1 dBFSのピークリミッターを適用し、H.264 CRF 17 + AACでエンコードし、フリーズ/ブラックおよびラウドネスのQAを実行し、out/qa_sheet.jpgを書き出します。シートを確認します。0.4秒以上のフリーズスパンやブラックフレームがある場合は修正が必要です。- MP4をSendUserFileで配信し、各ショットの内容を数行で説明します。キャプション、微調整、またはリストからの次のアイデアを提案します。
エンジンの落とし穴(キットに保存されています。再構築する場合は保持してください)
#include <fog_vertex>/<fog_fragment>は独自の行に配置します。- 最終パスは
linearToOutputTexel(...)を書き込みます(レンダーターゲットはリニアHalfFloatです)。 - 法線+深度パスはメッシュごとにマテリアルを交換します:ワールド → 法線/深度、カード → アルファテストマスク(rgb 0、a = depth)、ブロブ/雲/空は非表示、水 → フラット法線。フォグとシャドウはこの間オフになります。
- インクは深度ジャンプの手前側のみに適用されます。折り目は法線ドットから来ます。カードの隣接部分はスキップされます。インクは約140〜520mでフェードアウトします。
- 被写界深度:48タップ、サンプルごとのCoCテスト(前景ブリードなし)。
- 太陽は光プリセットごとにaz/elから来ます。シャドウカメラは各ショットのアクションの中心に配置されます。
アーキテクチャ(キット編集のためのリファレンス)
web/index.htmlはローカルHTTPサーバー上でmain.js(ESモジュール)を読み込みます
…
[翻訳のため一部省略]