カートゥーン短編:アイデア → 脚本 → ナレーション → 完成MP4
見た目:キャンバスに描かれた「カード」(プラム色の輪郭線)のような、平たい2Dの豆頭カートゥーンキャラクターが、黒いインクの輪郭線、ペイントされたテクスチャ、被写界深度、そして滑らかなカメラワークを持つカラフルな3D世界で動きます。出力は1080x1920、30fpsで、ナレーションと同じ長さになります。ユーザーの声はそのまま変更されません。BGMと効果音は合成され、BGMは声より16 dB低く、効果音は声の50 %以下のレベルになります。「決して去らなかった兵士」(19.7秒、8カット)で実証済みです。
このスキルがチャット内のファイルとして届いた場合
ユーザーが SKILL.md と cartoon-short-kit.zip を送り、「このスキルを読んで、インストールして、使ってください」(اقرأ هذه المهارة، وثبّتها، واستخدمها)などと言うかもしれません。その場合:
- このファイル全体を読み、それに従ってください。スキルが何かを説明したり、セットアップの質問をしたりしないでください。
- キットを書き込み可能なフォルダに解凍します(4.0参照)。
engine/main.jsとvendor/three.module.jsが存在することを確認してください。 - この環境に個人用スキルフォルダ(例:
~/.claude/skills/)がある場合、SKILL.mdとキットをそこにあるcartoon-audio-short/にコピーします。ない場合は、永続的にインストールされたとは言わず、このチャットで使用する準備ができており、新しいチャットでは2つのファイルを再度送信する必要があることを1行で伝えてください。 - 1行の短い返信をして、すぐにステージ1に進んでください。
言語:アラビア語または英語
- チャット: 最初の返信から、ユーザーのメッセージの言語で回答します。ユーザーがアラビア語で書いたり、アラビア語を要求したりした場合、すべてのメッセージはアラビア語(質問、オプションラベルと説明、タスクリスト、アイデア、進捗メモ、エラー、納品メモを含む)になります。簡単な日常的な言葉を使い、ユーザーが方言で書いた場合はそれに合わせてください。英語はファイル名とコマンドのためにのみ使用し、右から左のテキストがそれらを乱さないように、それらを独立した行に配置します。
- 脚本: 脚本の言語は、ユーザーが別の指定をしない限り、チャットの言語に従います。どの質問に対しても「أريد أفكار بالعربي」と入力すると、アラビア語でステージ2に進みます。
- アラビア語のバリエーション: ユーザーが方言(イラク、エジプト、湾岸、レバントなど)を書いたり要求したりしない限り、簡単な標準アラビア語で書きます。立ち止まって尋ねないでください。脚本の返信の最後に、次の1行を追加します:「تريده بلهجة ثانية؟ اكتب اللهجة وسأعيد كتابته。」(別の方言が欲しいですか?方言を書いてください。書き直します。)標準語と方言を、ユーザーが要求しない限り、1つの脚本内で混在させないでください。
- アラビア語での固定質問。 次の表現を使用します:
- 「من أين نبدأ?」(どこから始めますか?)
- 「الصوت جاهز」(音声準備完了):音声ファイルと、もしあればテキストをアップロードしてください。動画を作成します。
- 「عندي نص」(脚本あり):脚本を磨き上げ、録音のヒントをお伝えし、音声がアップロードされたら動画を作成します。
- 「أحتاج إلى أفكار ونص」(アイデアと脚本が必要):10個の独創的なアイデアを提案し、選択されたアイデアに基づいて脚本を書きます。
- 「كم مدة الفيديو?」(動画の長さは?)
- 「من 20 إلى 30 ثانية(مُوصى به)」(20~30秒(推奨)):約40~60語。
- 「من 30 إلى 45 ثانية」(30~45秒):約60~90語。
- 「من 45 إلى 60 ثانية」(45~60秒):約90~120語。
- 「من أين نبدأ?」(どこから始めますか?)
ルール
- ストーリー、キャラクター、カットは常にオリジナルです。他のクリエイターの動画をそのまま再現しないでください。代わりに、同じアイデアに対するオリジナルの解釈を提供してください。
- 実在の名前を持つ存命人物をキャラクターにしないでください。また、ブランドのマスコットやロゴも使用しないでください。
- ユーザーが要求しない限り、キャプションは付けないでください。物語内のテキスト(刻まれたメッセージ、看板)は問題なく、正しく読めるようにしなければなりません(鏡像にならないように)。看板、ラベル、見出しは脚本の言語を使用します。アラビア語の動画には「SOLD」ではなく「بِيعَ」と表示します。これらは4.3で説明されているように描画します。
- 声を編集したり、タイミングを変更したりしないでください。映像は声に合わせてタイミングが調整され、すべての視覚的な反応は、その単語の0~3フレーム前に配置されます。
- オーディオレベル: BGMは声より16 dB低く(ゲートRMS)配置され、ナレーションがクリアに聞こえるようにします。効果音は50 %以下で配置し、ピークはクリップされ、どの効果音もナレーションからはみ出さないようにします。常に
mix.pyでミキシングし、手動では行わないでください。この比率を変えるようなダッキングやコンプレッションは使用せず、ミックス全体には1つのリニアゲインとピークリミッターのみを適用します。 - タスクリストでユーザーに情報を提供し続けてください。長時間のレンダリングの前に、スチル写真のコンタクトシートを送信してください。
ステージ1:受付(常に最初)
音声ファイルがすでに添付されている場合は、ステージ4にスキップします。脚本も提供されている場合は、それをタイミング調整に使用します。 それ以外の場合は、AskUserQuestion(そのツールがない場合はプレーンテキスト)を1つ尋ねます:「どこから始めますか?」
- ナレーション準備完了:音声ファイルと、もしあれば脚本テキスト(脚本があるとタイミングが正確になります)をアップロードするよう依頼します。アップロードされたらステージ4に進みます。
- 脚本はあるが、ナレーションが必要:必要に応じてステージ3に従って脚本を引き締め、録音のヒントとともに返し、アップロードを依頼してからステージ4に進みます。
- 動画のアイデアと脚本が必要:ステージ2に進みます。 また、ユーザーが指定していない場合は、目標の長さも尋ねます。デフォルトは20~30秒、45~60秒も許可されます。アラビア語のチャットでは、「言語」の下の表現を使用します。
ステージ2:10個の動画アイデア
1つの返信で正確に10個のアイデアを番号付きで提示し、ユーザーに番号(または「もっと」)で返信するよう依頼します。各アイデアには次のものを含めます:
- タイトル(5~8語、好奇心をそそるもの。例:「決して去らなかった兵士」)。
- フックライン:最初に話される文。事実として述べられる逆説(「男がエッフェル塔を売った。二度も。」)。
- どんでん返し:1行で(動画の最後に明かされる皮肉な結末)。
- アニメーションに適している理由:2~3の大きな視覚的瞬間(崩壊、暴露、追跡)。
- 真実か伝説か:文書化された歴史なのか、議論のある話なのか、民間伝承なのかを明確に述べます。
このフォーマットに「完璧な」アイデアの条件:
- 物理的な因果関係があり、映像で示せる驚くべきストーリー。
- 明確な普通のキャラクター、エスカレートする stakes、最後の行でのどんでん返し。
- シンプルな3D形状とカートゥーンカード(町、橋、船、城、砂漠、研究所、宮殿)で構築できる設定。
- 時代とテーマ(古代、中世、1800年代、近代、科学、動物、発明、災害、奇妙な法律、幸運な偶然)にわたって10個を混ぜます。
- 真実として提示するものについては、提供する前にウェブ検索で重要な事実を確認してください。バイラルな伝説を事実として提示しないでください。ユーザーがどうしてもそれを望む場合は、「伝説によれば」と枠組みを設定します。
- 実在の存命人物を冗談の対象にしないでください。また、グラフィックな内容や政治的な内容も避けてください。
アラビア語のアイデアの場合:
- タイトル、フック、どんでん返し、メモをアラビア語で書きます。フックは翻訳ではなく、自然なアラビア語の文として書きます。外国の名前は通常のアラビア語の綴りで表記します。
- アラブ・イスラムの歴史と科学からのストーリーと、世界のストーリーを混ぜ、リストがこの視聴者向けに作られたように感じさせます。
- アラビア語と英語の両方で検索します。人気のあるアラビア語のストーリーも出典なしで広まることがあるので、同様に真実か伝説かでラベル付けします。
- 預言者、その仲間、または他の神聖な人物をキャラクターとして決して描かないでください。宗教、宗派、部族、国籍について冗談を言わないでください。
ステージ3:脚本(アイデア選択後)
ナレーションのみを書きます(話されるテキスト内のステージ指示はありません)。英語は約3.7語/秒でサイズ設定されます:20秒 ≈ 75語、30秒 ≈ 110語、60秒 ≈ 220語。アラビア語はより遅く、約2語/秒です:20秒 ≈ 40語、30秒 ≈ 60語、60秒 ≈ 120語。 アラビア語の単語はより多くの音節を含み、実際のアラビア語の声は1.6~2.1語/秒と測定されています。公式:
- フック(文1、前置きなし):不条理な事実。
- 設定 1~2行:いつ、どこで、誰が、具体的な詳細。
- エスカレーション、2~4ビート、それぞれがより大きく。他者は疑ったり嘲笑したりする。1つの誇張されたジョークを使用します。
- 謎または転換点:「しかし…」「実は…」で、本当のメカニズムを導入し、しばしば日常的な類推を用います。
- どんでん返し/結末:短く、皮肉的で、動画の最後の言葉。 平易な話し言葉の英語、短縮形、8~15語程度の文を使用し、数字は言葉で書きます。視聴者がすでに見ているものを説明しないでください。
アラビア語の脚本の場合:
- 文は約6~12語に保ち、同じ5部構成の公式を使用します。「لكن عندما…」(しかし…の時)や「والسبب?」(その理由は?)のような転換点がうまく機能します。
- 数字と年は言葉で書き(ألف وتسعمئة وأربعة وتسعون)、外国語の単語やブランド名はアラビア文字で綴り、声が正しく読めるようにします。
- 声のために句読点を打ちます:「،」と「。」は呼吸、「…」は暴露前の間、「?」は疑問文用です。タイミングもこの句読点を使用します。
- 音声生成器に貼り付ける準備ができた、コピー可能な音声ブロックを1つ提供します:
- すべての単語にタシュキールを付けます。これは、複数の読み方がある名前や単語に最も役立ちます。ナレーターが言わないであろう語尾の格変化は省略し、方言は話されている通りに書きます。タシュキール不要の要求があった場合、または適切に聞こえない場合は、削除します。
- 英語のEleven v3用のオーディオタグ。例:[excited]、[curious]、[serious]、[whispers]、[warmly]。文グループごとに最大1~2個、言葉がそれらに値する場所にのみ使用します。
- イラク語の「g」: 話し言葉の音で必要な場所にگとچを書きます(تِگْدَر、لْگِيت)。なぜなら、كは「k」と読まれるからです。
- パート: 約700文字を超える脚本の場合は、文の終わりで番号付きのパートに分割します。
- 語数と長さは上記のアラビア語のレートを使用し、タグとタシュキールは無視します。
その後、次のように返信します:
- 語数と推定時間を含む、コピー可能なブロック内の脚本。
- 1段落の視覚的計画(アニメーション化するショット)。
- 録音のヒント:1つの安定した、温かみのあるナレーターの声。ElevenLabsがうまく機能します(深みのあるナレーターの声、速度約1.05~1.1、安定性約45~55%)。Mp3またはwavで問題ありません。文の終わりで自然な間を残します。音楽なしでエクスポートします。
- アラビア語の録音のヒント:Eleven v3を使用します。古いモデルは[tags]を読み上げてしまうためです。StabilityをNaturalに、速度を約0.95に設定して開始し、すべてを生成する前に最初の文章を試してください。別の生成器を使用する場合は、最初にタグを削除してください。ユーザー自身の声でも機能し、その場合はタグやタシュキールは必要ありません。
- 依頼:「ナレーションが準備できたらアップロードしてください。完全な動画を作成します。」 最終的な脚本テキストを保持します。これはステージ4のタイミング調整の基礎となるため、音声認識は必要ありません。ユーザーが変更したバージョンを録音した場合は、最終テキストを尋ねます。
ステージ4:動画の構築(ナレーションアップロード後)
ここからは停止せずにすべてを実行します。タイミングが解決できない場合にのみ質問します。
4.0 キットを入手する
コードキットには、エンジン、ツール、実例、ベンダー提供のthree.js r160、github.com/mromidev/claude-animated-shortsからのtoon.ts Penライブラリ(両方MIT)、そしてLalezarアラビア語フォント(SIL OFL)が含まれています。次の順序で見つけ、読み取り専用として扱います:
- この
SKILL.mdの隣にあるkit/フォルダ。find / -name SKILL.md -path "*cartoon-audio-short*" 2>/dev/nullで見つけます。 - すでに解凍された
cartoon-short-kitフォルダ。 - このチャットで送信されたファイルの中の
cartoon-short-kit.zip:find / -name "cartoon-short-kit*.zip" 2>/dev/nullで見つけ、~/cartoon-short-kit-src/に解凍します。キットは、その中にあるengine/を含むフォルダです。
次に、bash <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:
--use-angle=swiftshader --enable-unsafe-swiftshader --ignore-gpu-blocklistを指定して、プリインストールされたPlaywrightブラウザを使用します。これにより、CPU WebGLが1フレームあたり約3~10秒で提供されます。
4.1 タイミング調整
python3 timing.py voice.mp3 script.txt --out work を実行します。脚本がない場合は、アラビア語の場合 --lang ar を追加します。脚本は正確な音声ブロックにすることができます。これにより、[tags]とタシュキールが削除され、アラビア語の句読点でもフレーズが分割されます。
- whisperまたはfaster-whisperがインストールされている場合、単語のタイムスタンプを使用します。アラビア語の場合は多言語モデルを使用し、脚本の単語自体を保持するため、聞き間違えられた方言の単語がテキストを変更することはありません。
- それ以外の場合は、脚本のフレーズ(句読点で分割)を、無音検出された音声セグメントに整列させます。これは、音節と継続時間を一致させ、セグメント内の文末とフレーズ内の長いギャップにペナルティを課すDPを使用します。
- ASRも脚本もない場合は、脚本を尋ねます。Claudeは音声を聞くことができません。
work/phrases.jsonを確認します:ポーズは文末にあるべきです。総フレーム数 = round(継続時間 × 30)。
4.2 ショット計画(コードの前の work/PLAN.md)
ショットごとに1行:フレーム、単語、設定、照明、カメラの動き、キャラクター/ポーズ/表情、エフェクト、効果音の合図。
- フレーム0はすでにフック画像です。
- 通常、フレーズごとに1ショット。非常に短いフレーズは次のショットにマージします。
- すべての文を文字通りに描写します。小道具がジョークを伝えます。
- ショットサイズを変えます:フックMCU → ワイドな明かし → 2ショット → キーとなるオブジェクトへのインサートクローズアップ → リアクションクローズアップ → 結末のための環境移動。
- ビートに光を使用します:日中は通常、金色は衰退やドラマ、夜の青は説明用。時間の飛躍には6フレームの白いフラッシュを使用します。
- どんでん返しの行にはスティング(音楽停止、低いヒット、プッシュインとロール)が入ります。最後のショットの物理的な結末は、最後の単語に合わせて配置されます。
4.3 ワールド(web/main.js)
エンジンセクション(トゥーンマテリアル、インクコントラクト、add/tbox、空、ライト、カード、レンダーターゲット/ポスト、applyLight、drawActors、swapForNd、renderFrame)を保持します。// ---------- world ---------- と // ---------- cards ---------- の間、および worldState() のストーリーパートにあるサンプルワールドを置き換えます。
-
ペイントされたキャンバステクスチャ(
paint.js:板、梁、腐った木、石、苔/ツタ、草、土、しっくい、屋根瓦、大理石、旗、刻まれたテキスト)を備えたプリミティブから構築します。同じフラットで暗い隙間のあるスタイルで新しいペインターを記述します。 -
一定のテクセル密度、2段階トゥーングラデーション、フォグ=地平線の色には
tboxを使用します。 -
背景:丘(半分埋まった球体)、山(円錐+雪のキャップ)、糸杉/松の木、遠くの家、ペイントされた雲のビルボード。
-
設定ピース(崩壊、落下、ドア)は、
worldAt(f)からの0..1の進行度で駆動されるピボットグループであり、イーズアウトとずらしたパーツを備えています。 -
湾曲したダイジェティックテキストは、平面UVを使用します。ミラーリングされていないことを確認します。
-
あらゆるもののアラビア語テキスト: 看板やタグには
P.signCanvas(text, opts)とP.tex()を、独自のキャンバスにテキストを描画するにはP.drawText()を、彫刻にはP.carvedText()を使用します。これらは、バンドルされたフォントを読み込み、右から左に設定し、文字列全体を描画します。アラビア文字を一文字ずつ決して描画しないでください。 -
カード: 常に
P.stripes()(水平な「紙」のテクスチャを持つ板)上にあり、顔と体は並んだ楕円形(P.ovals())で描かれます。脚は短く、揺れません。顔は正面を向いています。アームは円柱(P.arms())で、手は描きません。ポーズはP.idle()、P.point()、P.spread()、P.cover()、P.surprise()、P.think()。ショットはカットのみで、カメラはP.cutTo(f, cam)とP.moveTo(f1, f2, cam1, cam2, ease)で動かします。すべてのカード関数はworldとf(現在のフレーム)を引数として受け取ります。
4.4 レンダリング
cd ~/shorts/<slug>
python3 tools/mix.py voice.mp3 work/score.json output.mp3 && \
node web/main.js work && \
ffmpeg -r 30 -i work/frames/frame_%06d.png -i output.mp3 \
-c:v libx264 -pix_fmt yuv420p -profile:v high -preset slow \
-crf 18 -c:a aac -b:a 192k -shortest final.mp4
- フレームが欠落している場合:
for f in work/frames/frame_*.png; do [[ -f "$f" ]] || cp work/frames/last_good.png "$f"; done。 mix.pyが最終的なオーディオミックスを生成します。ピーク制限を適用し、すべてのトラックを正規化します。手動でオーディオを調整しないでください。- ffmpegが遅すぎる場合:
-preset ultrafast -crf 28を試してください。最終バージョンでは-preset slow -crf 18。 - ファイルサイズは通常15~25MBです。
4.5 配信
- 情報を提供し続ける: 各主要なステップの完了時にタスクリストを更新します。
- コンタクトシート: レンダリング前に、全ショットのスチル画像をグリッドで送信します。
python3 tools/contact-sheet.py work/framesは、フレーム0、ショット中央、最後のフレームから選択します。ユーザーに変更を依頼します。 - 最終動画:
final.mp4が完了したら、「どうぞ!」または「هذا فيديوك!」(これがあなたの動画です!)と送信します。時間を尋ねられたら、「X秒、Yフレーム」と答えます。 - 完了したら停止します。「もっと見たい」と言われた場合のみ続けます。
トラブルシューティング
- Nodeメモリ不足:
NODE_OPTIONS="--max-old-space-size=4096" node web/main.js work。 - Pythonが遅い:
numbaをインストールするか、小さなフレームバッファを使用します。 - アラビア語のテキストが反転する:
P.signCanvas()が正しいレンダリングを処理します。canvasを直接操作する場合は、ctx.save(); ctx.scale(-1, 1); ctx.textAlign = 'right'; ... ctx.restore();を使用します。 - 音声が音楽に埋もれる:
mix.pyでレベルを確認します(BGMは-16 dB、効果音は-6 dB以下)。手動で調整しないでください。 - Playwrightのエラー:
--use-angle=swiftshaderが設定されていることを確認します。それでもエラーが出る場合:xvfb-run node web/main.js work。 - フォントが見つからない: キット内の
Lalezar-Regular.ttfへのパスが正しいことを確認します。
付録:キットの構造
cartoon-short-kit/
├── engine/
│ ├── main.js # 3Dエンジン、カード、ワールド
│ ├── toon.ts # Penライブラリ(MIT)
│ ├── paint.js # キャンバステクスチャ用ペインター
│ └── fonts/
│ └── Lalezar-Regular.ttf
├── tools/
│ ├── setup.sh # プロジェクトのセットアップ
│ ├── timing.py # 音声→脚本の整列
│ ├── mix.py # オーディオミキシング
│ └── contact-sheet.py # スチルコンタクトシート
└── vendor/
└── three.module.js # three.js r160
付録B:カードAPIリファレンス
すべての関数は world オブジェクトと現在のフレーム f を最初の2つの引数として受け取ります。
ジオメトリ
P.box(w, h, d)、P.sphere(r, seg)、P.cylinder(r, h, seg)、P.plane(w, h)P.ground(w, d):地面平面
カードキャラクター
P.card({ face, body, arms, legs, color }):カードキャラクターを作成P.face({ eyes, mouth, brow }):顔のパーツP.arms({ left, right }):腕のポーズP.legs({ stance }):脚のスタンス
アニメーション
P.tween(obj, props, duration, ease):プロパティのトゥイーンP.sequence(animations):アニメーションの連続再生P.parallel(animations):アニメーションの同時再生
カメラ
P.cutTo(f, cam):カメラを即座に設定P.moveTo(f1, f2, cam1, cam2, ease):カメラをトゥイーン
テキスト
P.signCanvas(text, opts):テキストでペイントされたキャンバスP.drawText(ctx, text, x, y, opts):キャンバスに直接テキストを描画P.carvedText(text, opts):彫刻されたテキストの3Dジオメトリ
エフェクト
P.particles(count, opts):パーティクルシステムP.light(type, opts):ライトの追加P.fog(color, near, far):フォグの設定