make-short について
make-short は Remotion を使ってコードで縦型ショート動画を制作するワークフローです。脚本、アニメーション、フレーム単位の QA、音声、効果音、任意の音楽までを段階ごとに進めます。
主な機能
- 01脚本とタイミング付きビートデータの作成
- 02TSX による縦型 Remotion コンポジション
- 03最終出力前のフレーム単位チェック
- 04単語ごとのタイミング付き音声生成
- 05効果音と任意の音楽の設計・ミックス
活用シーン
- 01実写素材なしでアニメーション短編を制作
- 02テーマをタイミング付きの映像台本に変換
- 03音声と字幕を同期して追加
- 04短編向けの効果音と音楽を試聴
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ hassancs91/ claude-faceless-shorts-creator --skill make-shortインストール後、Claude Code で/make-shortを入力して読み込まれたか確認します。
詳細
make-short — エンドツーエンドの完全TSX製縦型ショート動画
すべてコードで作成します。映像素材やストック素材は使いません。1本のショート動画は、beatsコントラクトを受け取る1つのRemotionコンポジションで構成し、レンダリング後に音声と効果音を重ねます。shorts/ にある12本のサンプルショート動画で実証済みです。アイデアバンクとニッチのランキングは IDEAS.md にあります。トピックを選ぶときに読み、ブレインストーミングの際に追加してください。
すべて リポジトリのルート から実行します。ツールは標準ライブラリのみを使うPython 3.10+製です。ffmpeg/node を PATH に設定し、APIキーは .env に記載してください(.env.example を参照)。
成果物の契約
shorts/short-N-<niche>/
script.md — hook, beat sheet table (time | on screen | VO), production notes
beats.json — machine contract: format, vo[] (text+start/end+words), beats[], niche timeline
voice/ — per-line TTS clips + voice.wav (gen_voice.py) [gitignored]
sfx-plan.json — cue sheet on the global timeline (mix_sfx.py)
output/ — short-N-sfx.mp4 (+ music auditions) [gitignored]
remotion/src/shots/short-N/
ShortN<Name>.tsx — THE composition (registered by npm run gen)
vo.gen.ts — AUTO-GENERATED VO with exact word times (never hand-edit)
共通キット:remotion/src/lib/shorts.tsx(Captions、Kicker、BigTitle、Stamp、PauseCard、StatChip、ProgressBar、ShortsBackdrop、SAFE領域、progヘルパー)。これまでのニッチ用ライブラリ:lib/chess.tsx、lib/math.tsx、lib/algo.tsx、lib/sheet.tsx、lib/piano.tsx、lib/prob.tsx、lib/map.tsx、lib/orbit.tsx、lib/chart.tsx、lib/story.tsx… 新しいニッチ用ライブラリは、1本のショート動画につき最大1つだけ追加し、シリーズで使える汎用性を持たせてください。
ステージ1 — 台本とビート
ビートの構成(約38~42秒):フック(0~3.4秒。フレーム0ですでにすべてが構成され、オチが見えている状態にし、黒からフェードインしない)→ セットアップ → 任意の クイズ(PauseCard、約2.5秒。コメントを促します)→ リビール(2~4段階で展開し、それぞれナレーションの単語に同期)→ ひねり → ループ(最後のフレームをフレーム0と同じにし、オチをイントロへと溶け込ませて、シームレスに再生が繰り返されるようにします)。
アウトロは余計な要素なし。 昔ながらのエンゲージメント目的のCTAで締めるのは厳禁です。「次は何をすればいいですか?」「下にコメントしてください」「どれを解説しましょうか?」などは入れません。古くさく感じられます。オチのセリフで締め、映像の ループ でイントロにつなげてください。イントロにつながるループ自体が締めです。最後のフレームがフレーム0にぴったり一致する、すっきりした映像のディゾルブ/リセットを優先してください。トピックの特性上、シームレスなループがどうしても実現できない場合は、余計な内容を加えず、オチで締めてください。終盤を引き延ばさないでください。オチの直後に終わるようコンポジションを短くし、無音の時間が何秒も続かないようにします。
ナレーションのルール:約100語を目安にします。各行の表示時間は、次の行の開始時刻まで余裕を持たせて、約2.7語/秒 で見積もってください(詰め込みすぎると音声を速める処理が目立ちます。3.3語/秒では1.3倍速への圧縮が必要でしたが、2.7語/秒では最大1.11倍速でした)。台本を書く前に事実を検証してください。script.md と beats.json を作成します(ナレーションの各行に推定開始時刻と終了時刻を設定し、ニッチのタイムラインは全体の秒数で記述します)。
ステージ2 — コンポジション
remotion/src/shots/short-N/に.tsxを1つ作成し、compositionConfigは1080×1920、30fps、約42秒にします。vidtsx-2d-generatorの厳格なルール(フレームのみを使用、範囲は単調増加、Easing.bezier)に従ってください。- ビートは、1つの持続するキャンバス上の
<Sequence>シーンとして構成します(ボード/方程式/配列が連続性を保ちます。巻き戻しや進化はカットではなく、単一コンポーネントのタイムライン内で表現します)。 Captions lines={VO}とProgressBarはルートに配置します(時間は全体のもの)。その下にシーンを配置してください。- 繰り返し発生する不具合:
<Sequence>内のフレームはローカルです。 全体のビートの秒数をシーン内のキューに変換するには、local_f = global_s*fps − sequence_fromとします。キューは必ず二重に確認してください。 - フレーム0のルール:フックのシーンでは
warmプロパティ(BigTitle/EqRow)と負のatを使い、フレーム0ですでにハイライト/スタンプが表示されている状態にします。ループのシーンでは、フックのパンチインを逆再生します(1から1.06へ拡大するのではなく、1.06から1へ戻す)。これにより動画をシームレスにループできます。 - セーフエリア:字幕ブロックはy1500付近の中央に配置します。下部340px/右側160pxの範囲には、重要な要素を置かないでください。
ステージ3 — QA(省略しないでください。毎回、実際の不具合が見つかります)
cd remotion && npm run gen # frames.mjs does NOT run gen-registry itself
node scripts/frames.mjs ShortNName 0,<beat-boundaries+hero-frames>,<last> --scale=0.5
すべてのPNGを読み、スマートフォンの画面サイズで確認してください。チェックリスト:フレーム0で画面が構成され、サムネイルとして見栄えがする · 各リビールが対応するビートと同期している · オチの要素に何も重なっていない · ナレーションに合わせてキッカーが切り替わる · 字幕がUI領域にかかっていない · ループのフレームがフレーム0とほぼ同じ。修正してフレームを再レンダリングし、その後に限り:
node scripts/render-all.mjs ShortNName --scale=1 # -> remotion/out/ShortNName.mp4
ステージ 4 — 音声(ElevenLabs、単語単位で正確なキャプション)
python tools/gen_voice.py --beats shorts/short-N-<niche>/beats.json \
--voice TX3LPaxmHKxFdv7VOQHJ --emit-ts remotion/src/shots/short-N/vo.gen.ts
/with-timestampsを使った行ごとの TTS → 実際の単語ごとのタイミング(テンポに応じてスケーリング、グローバル)をbeats.jsonとvo.gen.tsに書き込みます。ショットでは{ VO } from './vo.gen'をインポートし、キャプションが発話された単語を正確にハイライトします。音声トラックがある場合、タイミングを推定してはいけません。- クリップはテキストのハッシュでキャッシュされます。1 行を書き直した場合、その行だけに再課金されます。
- 音声:サンプルでは ElevenLabs のプリメイド音声「Liam」(
TX3LPaxmHKxFdv7VOQHJ)を使用しています。--voiceフラグを指定して再生成すれば、(自分のクローン音声を含む)任意の音声に差し替えられます。 - その後、コンポジションを再レンダリングして(キャプションのタイミングも調整)、マルチプレクサー処理を行います:
ffmpeg -i remotion/out/<Id>.mp4 -i shorts/.../voice/voice.wav -map 0:v -map 1:a -c:v copy -c:a aac -b:a 192k -t 42 remotion/out/<Id>-voiced.mp4
ステージ 5 — SFX(suggest-sfx の仕組み、ショート動画向け)
brand.md §7 と media/library/sfx/catalog.json を読みます。まずライブラリを確認し、本当に見つからない場合に限り、汎用レシピを palette.json に追加して python tools/gen_sfx.py を実行します。shorts/short-N-<niche>/sfx-plan.json を作成します(プレビュー = -voiced.mp4、出力先 = output/short-N-sfx.mp4)。
ショート動画向けの調整:作品内の動作音がコンテンツそのものです(駒のコトコト音、数字が飛び出す音など)。長尺動画より高密度にしてもかまいません。装飾的な効果音は optional: true のままにします。主役となる 2〜3 個の瞬間を重ねます(キャプチャ+スタンプ、飛んで着地する動き+チャイム)。効果音のタイミングは、正確な着地フレームから求めます:
at_s = (move.at + move.dur + sequence_from) / fps。
PYTHONIOENCODING=utf-8 python tools/mix_sfx.py shorts/short-N-<niche>/sfx-plan.json --print
PYTHONIOENCODING=utf-8 python tools/mix_sfx.py shorts/short-N-<niche>/sfx-plan.json
ミックスはオーディション用です。最終版とする前に、ユーザーの耳による確認を必ず行います。
その後、カタログの used_in を更新します。
ステージ 6 — 音楽(任意、動画ごと)
media/library/music/ にあるライブラリの楽曲(追加生成には gen_music.py を使用)を使います。SFX ミックスに重ねて試聴します:
python tools/mix_music.py --all --base shorts/short-N-<niche>/output/short-N-sfx.mp4
(または --bed <id>)。音声の下では強くダッキングします。
完了条件 =
script.md と beats.json を作成済み(事実を検証済み) · コンポジションをフレーム単位で QA 済み · スケール 1 でレンダリング済み · 単語単位で正確なキャプション付きの音声を生成し、マルチプレクサー処理済み · SFX プランを作成し、試聴用にミックス済み(約 −15.5 LUFS、ユーザーの耳による確認待ち) · ライブラリの used_in を更新済み · IDEAS.md のキューを更新済み。