Faceless Shorts (フェイスレス・ショーツ)
トピックから完成した縦型ショート動画(スクリプト、音声、単語同期キャプション、アニメーションショット、効果音、BGM)を生成し、MP4にレンダリングします。すべてコードです:キャンバス描画、ヘッドレスChromeキャプチャ、ffmpeg、ローカルのKokoro音声、ローカルのWhisper単語タイミング、numpyサウンド。AI画像や動画、APIキー、追加クレジットは一切不要。
SKILL = このファイルがあるフォルダです。プロジェクトは ~/faceless-shorts/<short-name>/ に置かれます。
1つのスタイル:マスコット解説者(mascot-explainer)。あなた(クリエイター自身)を、1枚の写真からコードで描かれたフラットな漫画マスコット(リギング、リップシンク付き)にし、「N個の簡単なステップ」を提示します:一度に1枚のカード、隅のバッジに打ち込まれるナンバータイル、ライブチェックリスト、単語ごとのヘッドラインキャプション、アクションごとのカメラシェイク+効果音。30〜45秒、9:16。ハウツー、ヒント、「Nステップで…」、テック/マネー/生産性の解説動画に最適で、クリエイター自身がブランドとなります。
スタイル = styles/mascot-explainer/style-sheet.png(独自コードで描かれた1枚の画像でのルック) + STYLE.md(ルール+エンジンマニュアル) + example/(そのままレンダリング可能な完全なプロジェクト)。計画を立てる前に、STYLE.mdを必ず全文読んでください。
0. コンピュータでの初回使用
bash SKILL/scripts/setup.sh を実行し、All set と表示されるまで待ちます(Node 22+、ffmpeg、Chromeを確認し、~/.faceless-shorts/venv を構築、Kokoro音声~340MBとWhisper small.en~0.5GBをダウンロード)。不足しているものは無料の公式方法でインストールし、パスワードが必要な場合は確認してから実行してください。その後、bash SKILL/scripts/selftest.sh で SELFTEST PASSED と表示されることを確認し、コンタクトシートを開いて名前と内容を確認してください。
1. ヒアリング(1メッセージで、デフォルト値は事前入力)
不明点のみを一度にすべて質問します:トピック(または「3つのアイデアを選んで」)、好きなショート動画のフォーマットへのリンク(任意)、長さ(デフォルト約30秒)、音声(SKILL/scripts/py SKILL/scripts/voice.py --list;デフォルト am_michael)、ナレーションモード:AI音声(デフォルト)・自分の録音(スクリプト確認後にユーザーが録音;words.py --audio)・キャプションのみ(音声なし;estimate.py)、音楽(内蔵BGM・なし・自分で用意したロイヤリティフリーのファイル)、エンドライン/ハンドル、および(任意で)1枚の真正面の写真と服装、または ~/faceless-shorts/_mascots/ に保存されたマスコットの名前。「そのままで」と言われた場合はデフォルト値を使用します。
2. 計画(1画面で表示し、その後待機)
表示する内容:タイトル・完全なナレーション(カットごとに1行、キャプションのチャンク付き:1. Look at the | real *sender address)・ショットリスト(各行:何が見えるか、何が動くか、どの単語のタイミングに合うか)・必要に応じてキットに追加する新しいコンポーネント・事実とその出典。「作成しますか?」と質問し、回答を待ちます。
スクリプトのルール。 人が実際に友人に話すように書きます:つなぎ言葉(「さて」「つまり」「でも」「だから」「ということは」)を使った、完全で流れるような文章。短いキャプションのような箇条書きにしないでください。35秒で約90〜110語。
1行=1カット:各文を自然な区切り(カンマ、「そして」「つまり」)で1〜3行に分割し、画像が1.5〜3.5秒ごとに変わるようにしつつ、音声は流れ続けます(voice.pyは各文全体を一度に発声します)。構成:実際の出典付きの数字を使ったフック、1行の約束、3〜6のステップ(「1つ目は…」で始まる)、明確な締めくくりのアクション。数字は発音通りに書きます(「ナナ」)。頭の中で声に出して読んでみてください:キャプションのように聞こえたら書き直します。オリジナル作品のみ:気に入ったフォーマットを参考にしても、他のクリエイターのスクリプトやショットをコピーしないでください。すべての事実は信頼できる情報源と照合し、script.jsonの「sources」にリストします。
3. ビルド
bash SKILL/scripts/new_video.sh mascot-explainer <short-name>で、~/faceless-shorts/<short-name>/に example をコピーします。script.json(行+キャプション+ギャップ;STYLE.md参照)を書きます。最初にマスコットを作成し(mascot.json、STYLE.md §2)、ポーズシートをレンダリングして、ショットを書き始める前にユーザーの承認を得ます。- タイミング:
SKILL/scripts/py SKILL/scripts/voice.py <proj>の後、SKILL/scripts/py SKILL/scripts/words.py <proj>を実行します(自分の録音の場合はwords.py <proj> --audio their.m4a、キャプションのみの場合はestimate.py <proj>)。 src/shots.jsを書き換えます:1行につき1ショット(または長い行の場合は2ショット)、それぞれcut(i)で配置し、キーモーメントをWd('word', line)で単語に合わせます。キット(src/core/kit.js)を再利用し、新しいコンポーネントはそこに追加し、スタイルのルックに合わせます。- プロジェクト内で:
node tools/capture.mjs check(CHECK OKと表示されること)→node tools/capture.mjs cues→SKILL/scripts/py tools/mix.py .→ QA(セクション4)→node tools/capture.mjs video renders/<name>.mp4。 1つのショットを繰り返し調整する場合:node tools/capture.mjs frames review/f "4.2,4.6"で確認します。
4. QA:確認していないフレームを決してユーザーに見せない
node tools/capture.mjs sheet review/all.jpg 0.5 10(0.5秒ごとに1フレーム、タイムスタンプ付き)でシート全体を読み、主要フレームはフルサイズで確認します。すべてのフレームで以下をチェック:
- 意味が通じるか? 一度に1枚のカード;マスコットのポーズがその行に合っている;プロップはそれを保持するものと一緒に動く。原因より前に結果が表示されていない。
- その瞬間のナレーションと一致しているか? 画像はその行の直前に切り替わる;表示は対応する単語のタイミングで行われる。
- 何かが衝突していないか? 腕、スタンプ、バーストがヘッドライン、カード、バッジ、チェックリスト、または互いに意図せず交差していない。
- キャプション: 1〜4語、アクセントの紫単語は最大1つ、スペルが正しい、単語が発話される前に表示されない。
- スタイルシート: パレットのみ、フラットシェイプ、ハードなインクシャドウ、赤は危険のみに使用。
- サウンド: 音声が音楽の上でクリア;効果音はソフト(耳障りなチック音やビープ音なし)。 修正し、シートを再レンダリングし、再チェックします。何を発見し修正したかをユーザーに伝えます。
5. 納品
MP4ファイルをユーザーに開いて見せます。さらに、35MBを超える場合は共有用コピー(ffmpeg -i in.mp4 -c:v libx264 -crf 21 -preset slow -c:a aac -b:a 160k -movflags +faststart share.mp4)、最適なカバーフレーム(capture.mjs frames)、タイトル、キャプション、5~8個のハッシュタグを提供します。自分の録音モードの場合は、各行のタイミングが記載されたスクリプトも渡し、読み合わせができるようにします。1ラウンドの微調整の修正を受け付け、変更された部分のみを再レンダリングします。
5b. Zapier経由でYouTubeに公開(ユーザーがアップロードを依頼した場合のみ)
すべての呼び出しはCode Modeツールを使用します:execute 内で tools.zapier.* として実行します(通常のツールとして呼び出さないでください)。実際のアップロードで一度検証済み;以下の値は正確です。
- 接続。
list_zapier_skillsにアップロード用の保存済みスキルがあればそれを使用します。なければYouTubeアプリが有効になっていることを確認します:discover_zapier_actions({ app: "YouTube" })→enable_zapier_action({ selected_api: "YouTubeV4CLIAPI", app_display_name: "YouTube", action: "upload_video" })。接続がまだ存在しない場合、manage_zapier_connections({ selected_api: "YouTubeV4CLIAPI" })がユーザー用の接続URLを返します。 - ファイルをホストする。 アクションの
video/thumbnailパラメータには、Zapierのサーバーが取得できるURLが必要です。ローカルパスはエラーの原因となります。MP4を一時ホストに置きます。以下の順序で試してください(すべて2026年11月3日テスト済み;Windowsではcurl.exeを使用):- a. litterbox(1時間~72時間の有効期限、最大1GB):
curl -F "reqtype=fileupload" -F "time=1h" -F "fileToUpload=@renders/<name>.mp4" https://litterbox.catbox.moe/resources/internals/api.php→ 直接URLがプレーンテキストで返されます。 - b. uguu.se(約3時間の有効期限、35MB未満のショート動画に最適):
curl -F "files[]=@renders/<name>.mp4" https://uguu.se/upload→ JSONを返します;files[0].url(d.uguu.se/...リンク)を使用します。 - c. catbox(永続的、期限切れなし):(a)と同じ呼び出しで、
-F "time=1h"なし。恒久的に公開されるため、ユーザーの了承を得た場合のみ使用します。 - 以下はスキップします(2026年11月3日に動作確認済みで壊れているため、再試行しないでください):0x0.st(アップロード無効)、tmpfiles.org(リンクはビューワーページで、生ファイルではない)、gofile.io(生ダウンロードにはアカウントトークンが必要)、file.io(curl APIがWebアプリにリダイレクト)、bashupload.com、temp.sh(停止)。
- URLを使用する前に必ず検証してください:
curl -sSI <url>が200/206と動画のContent-Typeを返すことを確認します。ホストのJSONを確認せずに信頼しないでください。 - この手順により、動画が自動的に期限切れになる公開一時ホストに置かれることをユーザーに伝えます。
- a. litterbox(1時間~72時間の有効期限、最大1GB):
- 事前確認。 これはユーザーの実際のチャンネルに書き込むため、実行前に確認します:タイトル、公開設定(非公開/限定公開/公開)、カテゴリ。必要に応じて、
inspect_zapier_actions({ tool_name: "youtube_upload_video", enum_property: "category_id" })でcategory_idを確認します。教育=27(ハウツーリールのデフォルト)、コメディ=23、ハウツー&スタイル=26。 - アップロード。
execute_zapier_write_action({ selected_api: "YouTubeV4CLIAPI", action: "upload_video", tool_name: "youtube_upload_video", params: { video: "<temp URL>", title, description(最後に #shorts を付ける), tags: [5〜8個のハッシュタグ(#なし)], category_id: "27", privacy_status, made_for_kids: false, embeddable: true, notify_subscribers: true, default_language: "en", license: "youtube" } }) - 報告。 結果に
idが含まれます;リンクはhttps://www.youtube.com/watch?v=<id>です。60秒以下の縦型動画は自動的にショートになります(追加フィールドは不要)。 ローカルファイルをユーザーに開いて見せ(tools.browser.preview({ path: "renders/<name>.mp4" }))、YouTubeのURLをテキストで提供します。アプリ内ブラウザはERR_ABORTEDでyoutube.comの読み込みに失敗することがありますが、それはアップロード失敗ではありません。 - サムネイル。 限定公開のアップロードでは、このアクションでカスタムサムネイルを設定できません。後でユーザーが動画を公開する場合に備えて、保存済みのカバーフレームを提供します。
禁止事項
AIで画像や動画を生成しない。ユーザーの費用やクレジットを使わせない。ユーザーが依頼し確認する前にYouTubeやその他のホストにアップロードしない。他のクリエイターのスクリプト、ショット、フレームをコピーしない。ユーザーのプロジェクトを確認なしに上書きしない。確認していないフレームをユーザーに見せない。