Communitygithub.com

michaelburshtein/thought-to-motion

トーキングヘッド動画、音声録音、またはプレーンテキストから、発言に合わせたモーションデザイン(RTL対応ワードタイムキャプション、キーワードカード、A/B表示、アイコン、エンドカード、ブランドテーマ、著作権フリー音楽)を備えた縦型(9:16)または横型(16:9)動画を生成します。完全にローカルで動作し(Whisper/ivrit.ai + Remotion + ffmpeg)、2つの人間による承認ゲートを設けています。

thought-to-motion とは?

このスキルは、トーキングヘッド動画、音声録音、またはプレーンテキストを、美しくタイミングの合ったソーシャルメディア動画に変換します。発言内のビート(重要なポイント、対比、質問など)を識別し、ワードタイムキャプション、キーワードカード、トランジションを自動生成します。3つのモード(トーキングヘッド、音声のみ、テキストのみ)と2つのアスペクト比(9:16と16:9)をサポートし、ブランド設定(テーマ、カラー、ワードマーク)を適用できます。完全にローカルで動作するため、どのプラットフォームでも安全かつプライベートに利用できます。ワークフローには、準備・プラン作成・承認(ゲート1)、静止画レビュー・承認(ゲート2)、レンダリング・納品のフェーズが含まれます。このスキルは、編集、キャプション追加、モーショングラフィックス、または「After Effects」のような処理が求められる短尺ソーシャル動画に特に適しており、ユーザーがすべてのクリエイティブな判断を制御できます。

対応✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/michaelburshtein/thought-to-motion-skill/tree/main/skills/thought-to-motion

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

thought-to-motion は何をしますか?

アイデアがプロダクトであり、それ以外はすべてレイヤーです。このスキルは、録音(トーキングヘッド動画または音声メモ)を取得し、発言のビートを見つけ出し、それらに合わせたモーションデザインを生成します。発言言語のキャプション、キーワードのカード、ひねりのある部分の表示、最後の質問などです。

3つのモード:

  • talking-head: 映像はそのまま残り、カード、キャプション、パンチインがその上に配置されます。
  • voice: 映像は不要(音声ファイル、または動画から抽出した音声)。シーン、キネティックキャプション、ライブ波形を備えた全画面ブランドキャンバスを使用します。
  • text: 録音は不要。プレーンテキストがタイミング調整されたキネティックキャプションとシーンになり、ブランドキャンバス上に配置されます(通常は背景音楽付き)。

2つのフォーマット: 9:16(デフォルト;Reels、TikTok、Shorts)と16:9("aspect": "16:9";YouTube、LinkedIn、ウェブ)。同じプランが両方でレンダリングされます。16:9では、9:16のレイアウトがワイドなステージ上に配置されます(トーキングヘッド:話者は右側にフレーミング、モーションデザインは左側)。

すべてこのマシン上で実行されます。映像、音声、テキストがどこかにアップロードされることはありません。

0. セットアップ(マシンごとに1回)

スキルフォルダから:

bash scripts/setup.sh          # venv + 固定パッケージ + ロックファイルからのengine/node_modules + ローカルサウンドキット

ffmpeg、Node 18+、Python 3.10+ が必要です。最初の文字起こしでは、huggingface.co(およびそのファイルCDN *.hf.co)からモデルを.cache/hfにダウンロードします。ネットワークアクセスが許可リストで制限されている場合、それらのホストを許可する必要があります。Chrome/Chromiumのヘッドレスシェルが既に存在する場合は、BROWSER_EXECUTABLE=/path/to/headless_shellを設定してください。そうでない場合、Remotionは最初のレンダリング時に独自のものをengine/node_modulesにダウンロードします。Pythonスクリプトは.venv/bin/pythonで実行します。

あなたのブランド(1回)

brand.example.jsonをbrand.jsonにコピーして記入します:ワードマーク(あなたの名前またはブランド)、シリーズラベル、ハンドル、ブランドライン、テーマ(warm、cinematic、またはtech。詳細はengine/src/lib/theme.jsを参照。独自の色やフォントを追加できます)。すべてのプランのbrand、theme、bumpersフィールドはこれから取得されます。brand.jsonがない場合 -> ヘッダー、イントロ、アウトロはありません。

1. インプット(推測できないことだけ尋ねる)

  • ソース。話している人物がいる動画 -> talking-head。音声のみ、または音声だけが重要な動画 -> voice(prepが音声を抽出します)。プレーンテキスト -> textモード。
  • フォーマット:9:16、16:9、または両方(異なるaspectで同じプランを2回レンダリング)。
  • 音楽:オンまたはオフ。組み込みの生成ベッドのみが埋め込まれます(calm / warm / pulse、著作権なし、クレームされるものはありません)。ユーザーが特定の曲を希望する場合は音楽をオフにしてください。後でアプリで追加します。
  • キャプション言語:デフォルト = 発言言語。第二言語用の2つのオプション:バイリンガル(1つの動画で、発言言語が上部に、その下に小さな翻訳:lang2 + text2)または別個のレンダリング。
  • テーマ(warm / cinematic / tech、詳細はengine/src/lib/theme.js参照)、ブランドワードマーク + シリーズラベル(またはなし)、およびクロージング質問/CTA(ある場合)。
  • Voiceモード:使用するユーザー自身の写真(<job>/public/に配置)。

2. 準備

テキストモード(録音なし):

.venv/bin/python scripts/prep_text.py <text.txt | "inline text"> <job> [--lang he|en] [--wpm 150] [--aspect 9:16|16:9]

テキストをフレーズ境界でキャプションサイズの行に分割し、快適な読み速度でタイミングを設定し、plan.draft.json(モード "text"、音楽 calm、モーション calm)を書き込みます。ユーザーの言葉を書き換えず、分割とタイミング設定のみを行います。その後、ボイスモードと同様にシーンをデザインします(セクション4)。セクション4に進みます。

動画または音声:

.venv/bin/python scripts/prep.py <media> <job> [--mode voice] [--lang he|en|auto] [--no-cut]

1080x1920 30fps(または音声)にノーマライズし、0.45秒以上のポーズをカットし、音声をクリーンアップし(DeepFilterNet3ノイズ除去 + EQ、デエッサー、コンプレッション、-14 LUFS;--clean gentleがデフォルト、非常にノイズの多い屋外クリップにはfull、スタジオ録音にはoff)、サウンドキットをコピーし、カットされたタイムラインを単語タイミングで文字起こし -> <job>/transcript.json。 ヘブライ語は自動的にivrit.aiモデルを使用します。スクリプトは信頼度の低い単語を出力します:最初にそれらを確認してください。

オプション:背景の置き換え(トーキングヘッド)

最良の結果 - クリーンプレートを撮影してください。 着席する前に、空の部屋を3〜5秒撮影し、その後入って話し始めてください。スマートフォンを三脚で固定し、露出とフォーカスをロックします(iPhoneの場合:画面を長押しして「AE/AFロック」)。部屋に入ったときに明るさが変わらないようにします。ズームやカメラの移動はしないでください。prep.pyは空のオープニングを自動的に検出し、正確な背景参照として保存し(work/clean_plate.png)、それを(および入場部分を)動画からカットします。クリーンプレートがない場合、エンジンは頭や胴体の後ろの部屋を推測する必要があります。空の部屋は、同じ固定されたスマートフォンの位置から撮影された別のクリップ(トークの前または後)でも構いません:

.venv/bin/python scripts/plate_from_clip.py <job> <empty_room_clip>

そのクリップの静止した空のオープニングのみを使用し(誰かが入ってきたら停止)、トークの背景に合わせて(ECC、アフィン変換)、チャンネルごとに露出と色を一致させます。処理前にwork/plate_check.jpg(トーク | プレート | 差分)と表示される一致数値を確認してください。

.venv/bin/python scripts/background.py <job> <plate.jpg> --draft [--reveal SECONDS]   # ドラフト:半分の解像度、約4倍高速
.venv/bin/python scripts/background.py <job> <plate.jpg> [--reveal SECONDS]           # 最終:フル解像度
# オプション: [--match 0.65] [--wrap 0.35] [--preview SECONDS]

ローカルポートレートマッティング(MODNet)とクリーンルーム差分マットの組み合わせ:固定カメラの場合、クリップの中央値が空の部屋になり、それと異なるもの(速い手、髪、腕)が人物として保持されます。空の部屋は、各スポットが実際に空であるフレームからのみ学習されます(最初に人物がマスクアウトされます)。そのため、頭の隣の実際の壁が人物と誤認されることはありません。半透明のエッジ(髪)はその空の部屋に対してデコンタミネーションされるため、古い壁の縁が表示されることはありません。机のライン(--desk auto:あごの下約1.2顔の高さ;または0.9のような割合;立ち位置のショットにはoff)より下にあるものはすべて人物の前にあります(机と置かれている前腕) - 撮影されたまま保持され、プレートに合わせて再照明されます。ハンドヘルド映像には--moving-cameraを使用します(モデルのみ)。話者の後ろの無地または緑の壁が最もきれいな結果をもたらします。その後、人物はプレートの明るさと色に再照明され、プレートの光が人物のエッジに回り込み、1つのビネットとグレインが両方にかかるため、1つのカメラで撮影されたように見えます。--revealはその瞬間まで実際の部屋を保持し、新しい部屋にワイプします(話者がカメラに向かってそれを要求する場合に最適)。常に1〜2フレームで--previewを実行し、クリップ全体を処理する前にユーザーに表示してください。処理後、scripts/bg_qa.py <job>を実行します:元の動画と新しい動画を1フレームおきに比較し、人物が失われた場所(赤)または古い部屋が漏れた場所(黄)を毎秒報告し、最悪のフレームのシート(work/bg_qa_sheet.jpg)を出力します。ユーザーが動画を見る前に、失敗している毎秒を修正またはフラグを立ててください。既知の誤検出:クリーンプレートと撮影の間で移動したオブジェクト(椅子、ドア)は「人物」としてカウントされます。その秒数に対処する前にシートを確認してください。プレートはシーンと一致している必要があります:屋内/屋外、時間帯、暖色/寒色の光、カメラの高さ。public/source_bg.mp4を書き込みます。

3. トランスクリプトを読み、修正し、キャプションを書く

  • 明らかな認識エラー(名前、スラング、混合言語の単語)を修正します。すべての修正をユーザーにリストアップしてください。意味を黙って変更しないでください。何が言われたか不明な場合は尋ねてください。
  • フィラー(「えーと」、「あー」)を削除します。キャプション:1つのアイデアを1つのキューに、<=約42文字、最大2行、読みやすい速度(<=約20文字/秒)、キュー時間は単語タイムスタンプから。
  • 第二言語:話者の声と同一のタイミングを保ちながら、自分でキューを翻訳します(バイリンガルキャプション用のtext2として;翻訳を1行に収まる程度に短くしてください)。
  • RTLキャプションでは、引用された英語は1つのまとまりとして保持します(「כי אני זוכר Is that cheese」)- エンジンが分離します。

4. モーションプラン -> ゲート1(承認)

最初にreferences/motion-rules.mdを読んでください。次に、references/prompts/内のステージプロンプトを順番に、自身の作業ステップとして実行します(これらはゲート用の素材を生成します;ゲートを置き換えることはありません):

  1. ストーリー&フックエディター(1-story-hook-editor.md):フック候補、未解決の質問とその解決点、アーク、カットリスト。逐語的なスパンのみ。テキストモード:代わりに6-text-to-video-writer.mdを使用します。
  2. キャプションデザイナー(3-caption-designer.md):チャンキング、読み速度、強調単語、RTL。
  3. モーションディレクター(2-motion-director.md):ビートごとに1つの要素、その単語にランディング、一度に1つの焦点、置き換えるのではなく変形。
  4. サウンドデザイナー(4-sound-designer.md):ランディングにまばらな音、音楽スタイル、1つの無音ビート。

ビートを見つけてください(references/design-rules.mdを参照):フック、名前付き参照(番組、人、場所、製品)、キーコンセプト、対比または選択、リスト、話者が実際に言った数字、ひねり/表示、質問/CTA。各ビートを要素にマッピングします(references/plan-schema.md)。以下の表をユーザーに提示します:

#時間発言内容要素理由教訓確認

また、ビデオのキャッチフレーズ(動画のメインアイデア、話者が実際に言うセリフ、約2〜3秒)をオープナー用に提案します。 さらにリストアップ:キャプションの修正、追加した画面上の事実(例:番組の年)とその出典、テーマ、サウンド。停止して承認を待ちます。 これ以前には何もレンダリングされません。

5. プランの作成と検証

<job>/plan.jsonを書き込みます(スキーマはreferences/plan-schema.md、例はexamples/内)。その後:

.venv/bin/python scripts/validate_plan.py <job>/plan.json

すべてのERRORを修正します。WARNを読み、重要なものを修正します。スキーマに加えて、モーションルールもリントします:0.5秒ごとのコンテンツ、視覚的イベントなしで6秒以上のギャップなし、同時に最大2つのグラフィック、読み速度(最大20文字/秒)、キャプション期間、パンチイン制限、ライトリーク安全性、効果音間隔、無音ビート。ルールを意図的に破る場合のみ、その理由をゲート2で説明してください。 バリデーターはセーフエリア(x 60-900、y 220-1420:アプリUIで覆われないフレームの部分)も強制し、すべてのカードとパネルを発表者の顔から遠ざけます(faces.jsonで追跡)。--fixを追加するとカードが自動的に移動します。references/safe-zones.mdを参照してください。

バーチャルカメラ(トーキングヘッド、自動)

.venv/bin/python scripts/shots.py <job> [--plan plan.json]

1つの固定ショットをマルチカメラ編集のように見せます:カメラA(ワイド、元のフレーミング)、B(ミディアム、約1.2倍)、C(クローズ、約1.4倍;16:9では最大1.7倍)、同じフレームから切り抜かれ、追跡された顔にアンカーされます。カメラの変更は、prepが作成したポーズカットにランディングし(ジャンプを隠す)、それ以外は文の終わりにランディングします。ショットは3〜8秒続きます。同じカメラが2回続くことはありません。ワイドはカードにスペースが必要な場合、クローズはパンチインと表示時に使用します。各ズームショットは約1.5%押し込みます(calm)。すべてのカメラはカードとキャプションに対してテストされ、顔がはっきり見えるようにします。9:16で顔の高さがフレームの3分の1より大きいクローズアップ自撮りの場合、バーチャルカメラは使用されません。近づくスペースがないためです。AI生成アングルはありません。映像は実際のものでありローカルに留まります。ゲート1の表に「カメラ」列(A/B/C)を追加してください。

6. 静止画 -> ゲート2(承認)

.venv/bin/python scripts/render.py stills <job>        # キーモーメント -> <job>/stills/sheet.jpg

シートにはガイドが表示されます:非セーフゾーンは赤、追跡された顔は緑。 まず自分で確認してください:すべてがセーフエリア内にあるか、顔/口を覆っていないか、ヘブライ語/英語の順序が正しいか、フォントが読み込まれているか(Timesライクのフォールバックがないか)、重なっていないか。 次に、独立したレビューアー(references/prompts/5-reviewer.md)を、あなたの推論を見ていない別のエージェントとして実行します:静止画、plan.json、トランスクリプトのみを与えてください。そのブロッカーを修正し、その判定結果を静止画とともにユーザーに表示します。停止して承認を待ちます。 レビューアーはユーザーに代わって承認することはありません。

7. レンダリング、確認、納品

.venv/bin/python scripts/render.py video <job> --name <NAME>            # レビュー用540x960ドラフト(デフォルト、高速)
.venv/bin/python scripts/render.py video <job> --name <NAME> --final    # フル1080x1920、最高品質

すべてのレビューレンダリングは**半解像度ドラフト(540x960)**です。承認された最終バージョンに対してのみ--finalをレンダリングします。キャプション言語ごとに1レンダリング(プラン内のlang + captionsを変更)。レンダリング後、確認:長さが一致するか、オーディオが存在するか、いくつかのフレームが正しく見えるか。MP4ファイル(1080x1920または1920x1080 H.264ハイプロファイル、faststart;Reels、TikTok、Shorts、YouTube、LinkedInに最適)と、その隣に書き出された.srtキャプションファイル(キャプション言語ごとに1つ)を納品します。プランに"music"が含まれている場合、ベッドはレンダリング時にミックスインされ、音声の下に自動的にダッキングされます。レンダリングには、2 CPUで動画1分あたり数分かかります。 --finalは<NAME>_social.mp4も書き出します:約10 Mbps(スケジューラーAPI、例えばInstagramの約300 MB制限に十分小さい)の同じ映像で、最終ファイル上でオーディオが再測定され、-14 LUFS / -1 dBTPにノーマライズされます。投稿用にそのコピーを納品し、高ビットレートのマスターをアーカイブとして保持します。納品されたファイルを測定し(ffmpeg -i <file> -af ebur128=peak=true -f null -)、そのラウドネスを報告します。動画は最後の音声の約0.8秒後に終了します(prepがそのテールを保持するため)。最後の単語がクリップされることはありません。プランに"bumpers"が含まれている場合、render.pyはオープナー -> イントロ -> 動画 -> アウトロを結合し(scripts/bumpers.py)、オープナー + イントロの長さ分だけ.srtファイルをシフトし、音声と映像の同期が取れていない場合は停止します(Opener, intro and outroを参照)。

ルール(譲歩不可)

  • 事実、数字、引用、ストーリーを決して捏造しないでください。トランスクリプトを超える画面上の事実(日付、タイトル)は検証され、ゲート1でユーザーに表示されなければなりません。
  • 認識可能なキャラクター、ロゴ、著作権で保護されたアートワークを描かないでください。タイプと組み込みの汎用アイコンを使用してください。例外:logo要素

...

[翻訳のため省略]

関連スキル