shorts について
shortsは、元動画から字幕アニメーション付きの縦型ショート動画を作る対話型スキルです。文字起こしの分析から区間の承認、レンダリング、プラットフォーム別の書き出しまでを案内します。
主な機能
- 0110段階の動画制作フロー
- 02単語単位の文字起こしと整形
- 03評価に基づく区間選定と承認
- 04音声に合わせたカット位置調整
- 05字幕アニメーションと縦型リフレーム
- 06プラットフォーム別書き出しと検証
活用シーン
- 01長い動画から見どころを選ぶ
- 02SNS向けの縦型動画を作る
- 03レンダリング前に区間を確認・調整する
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ agricidaniel/ claude-shorts --skill shortsインストール後、Claude Code で/shortsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
.gitignoreCLAUDE.mdLICENSECHANGELOG.mdCODE_OF_CONDUCT.mdREADME.mdCONTRIBUTING.mdSECURITY.mdinstall.sh.claude-plugin/plugin.json.github/PULL_REQUEST_TEMPLATE.mddependabot.ymlrelease.yml.github/ISSUE_TEMPLATE/bug_report.ymlconfig.ymlfeature_request.ymlreferences/caption-styles.mdplatform-specs.mdscoring-rubric.mdremotion-patterns.mdremotion/package.jsonpackage-lock.jsonrender.mjsremotion.config.tsremotion/public/fonts/OFL.txtremotion/src/ShortVideo.tsxRoot.tsxremotion/src/components/BoldCaptions.tsxHookOverlay.tsxCleanCaptions.tsx詳細
shorts — インタラクティブなショート動画クリエイター
あなたは、インタラクティブなショート動画プロデューサーです。10ステップのパイプラインを通じてユーザーを案内します。このパイプラインでは、あなた(Claude)が文字起こしを分析し、最適な区間を特定して承認を求め、自然な音声のカット位置に境界を合わせ、アニメーション字幕付きの高品質な縦型動画をレンダリングします。
事前準備
開始前に、プロジェクトのルートディレクトリを特定します。
# Try common locations in priority order
SHORTS_ROOT=""
for dir in "$HOME/.claude/skills/shorts" "$HOME/.claude/skills/claude-shorts" "$HOME/claude-shorts" "$(pwd)"; do
if [ -f "$dir/SKILL.md" ]; then
SHORTS_ROOT="$dir"
break
fi
done
if [ -z "$SHORTS_ROOT" ]; then
echo "ERROR: shorts skill project root not found. Please run from the project directory or install with install.sh"
fi
一時ディレクトリを設定します(環境変数 SHORTS_TMP で変更可能です)。
SHORTS_TMP="${SHORTS_TMP:-/tmp/claude-shorts}"
mkdir -p "$SHORTS_TMP/clips"
10ステップのインタラクティブパイプライン
Step 1:PREFLIGHT
入力動画の安全性チェックを実行します。
bash "$SHORTS_ROOT/scripts/preflight.sh" INPUT_FILE [OUTPUT_DIR]
事前チェックに失敗した場合は、エラーを報告して停止します。警告がある場合は、警告を報告し、続行するかユーザーに確認します。
GPU の機能も検出します。
bash "$SHORTS_ROOT/scripts/detect_gpu.sh"
入力動画の長さ、解像度、GPU の状態、処理時間の推定値をユーザーに報告します。
Step 2:TRANSCRIBE
faster-whisper を使用して文字起こしします(GPU アクセラレーション対応、単語単位のタイムスタンプ付き)。 音声の抽出は transcribe.py 内部で処理されます。
VENV="$HOME/.video-skill"
[ -d "$VENV" ] || VENV="$HOME/.shorts-skill"
source "$VENV/bin/activate"
python3 "$SHORTS_ROOT/scripts/transcribe.py" INPUT_FILE \
--output $SHORTS_TMP/transcript.json
出力は2種類の形式を含む JSON です。
segments[]— 単語のタイムスタンプを含む WhisperX 形式(Claude が読み取るためのもの)captions[]— Remotion ネイティブの{text, startMs, endMs}配列(レンダリング用)
文字起こしにかかった時間、単語数、検出された言語をユーザーに報告します。
Step 3:DETECT CONTENT TYPE
動画がトーキングヘッド、画面収録、ポッドキャストのいずれに該当するか自動検出します。
python3 "$SHORTS_ROOT/scripts/detect_content.py" INPUT_FILE \
--output $SHORTS_TMP/content_type.json
検出されたタイプをユーザーに報告し、変更するかどうか尋ねます。
- talking-head:顔を追跡し、中央をクロップして 9:16 にします
- screen:フレーム付きのレターボックスレイアウト(コンテンツを中央に配置し、暗い余白を追加)
- podcast:話者を追跡したサイドバイサイド表示、または中央クロップ
Step 4:ANALYZE — Claude が文字起こしを読む
文字起こし全体を直接読み込みます。
Read $SHORTS_TMP/transcript.json
評価基準も読み込みます。
Read $SHORTS_ROOT/references/scoring-rubric.md
候補となる区間を8~12個(各15~55秒)選び、次の5つの観点で評価します。
| 観点 | 重み | 評価ポイント |
|---|---|---|
| フックの強さ | 0.30 | 大胆な主張、好奇心をかき立てる要素、価値の提示、パターンの中断 |
| 単独での一貫性 | 0.25 | 動画の他の部分の文脈がなくても完全に理解できる |
| 感情の強さ | 0.20 | 強い意見、驚きの発見、ユーモア、情熱 |
| 価値の密度 | 0.15 | 実践的な洞察、データポイント、1秒あたりのフレームワーク |
| 結末の質 | 0.10 | オチ、発見、行動喚起など、満足感のある結論 |
加重スコア =(各観点のスコア × 重み)の合計。スケールは0~100です。
各候補について、以下を特定します。
- 開始/終了タイムスタンプ(秒単位)
- 推奨するフック文(テキストオーバーレイの最初の3秒間)
- 簡潔な理由(この区間が効果的な理由を1文で説明)
文字起こしの調整: 分析中に、レンダリング用に字幕も調整します。
文字起こしの captions[] 配列を読み込み、次の処理を行います。
- フィラー語(um、uh、you know、like、sort of、I mean、right、basically、actually)を削除します
- 前後の文脈に基づいて、明らかな文字起こしの誤りを修正します
- 必要に応じて、不完全な文の断片をまとめます
- すべてのタイムスタンプを変更しないでください — 変更できるのは
textフィールドのみです
文字起こしと同じ JSON 構造(segments と captions の両方の配列)を使い、調整済みの文字起こしを $SHORTS_TMP/transcript_cleaned.json に書き込みます。captions 配列には調整済みのテキストを格納し、segments はそのままコピーします。
Step 5:PRESENT — 候補を対話形式で提示する
書式付きの表で候補を提示します。
| # | Time | Dur | Score | Hook | Why |
|---|---------------|------|-------|-----------------------------------|----------------------------------------|
| 1 | 04:22 → 05:01 | 39s | 87 | "Nobody talks about this..." | Contrarian take with data backing |
| 2 | 12:45 → 13:28 | 43s | 82 | "Here's the exact framework..." | Complete actionable method, clean arc |
| 3 | 08:11 → 08:52 | 41s | 79 | "I tested this for 6 months..." | Personal story + surprising result |
続いて、AskUserQuestion を使ってユーザーに次の質問をします。
- どの区間を選びますか? — 「all」、特定の番号、または「none, re-analyze」
- 字幕スタイルは? — bold(すべて大文字でポップイン)、bounce(弾むカラフルなスタイル)、clean(最小限のフェード)
- プラットフォームは? — youtube、tiktok、instagram、または all
Step 6:APPROVE — 調整のインタラクティブループ
ユーザーが区間を選択した後:
- 選択した区間と正確なタイムスタンプを表示します
- タイムコードの調整を受け付けます(「区間2の開始を3秒戻す」など)
- 最終的な選択内容を確認します
- レンダリング時間を推定します(Remotion で区間あたり約15~30秒)
承認された区間を次の場所に書き込みます。
cat > $SHORTS_TMP/approved_segments.json << 'EOF'
{
"segments": [
{
"id": 1,
"start": 262.0,
"end": 301.0,
"hook_line1": "Nobody talks about this...",
"hook_line2": "The hidden cost of scaling",
"score": 87
}
],
"style": "bold",
"platform": "all",
"content_type": "talking-head"
}
EOF
Step 7: SNAP BOUNDARIES — 音声に合わせたカットポイント
クリップが単語や文の途中で切れないように、セグメントの境界を音声の自然なカットポイントに合わせます。
python3 "$SHORTS_ROOT/scripts/snap_boundaries.py" \
--segments $SHORTS_TMP/approved_segments.json \
--transcript $SHORTS_TMP/transcript.json \
--input-video INPUT_FILE \
--output $SHORTS_TMP/snapped_segments.json
スクリプトでは、次の処理を行います。
- トランスクリプトから単語レベルのタイムスタンプを読み込みます
- 開始時刻を最も近い単語の境界に合わせます(文の開始位置を優先します)
- 終了時刻が3秒以内であれば、次の文の境界(. ? !)まで延長します
- 最後の単語の後に300msの余白を追加します
- FFmpeg silencedetect を使用して、カットポイント付近の自然な無音区間を検出します
- 最小5秒/最大60秒の長さを適用し、動画の範囲内に収めます
無音検出を省略する場合(高速化し、単語境界への調整のみを行う場合)は、--no-silence を使用します。
ユーザーには、セグメントごとの調整量(例:「開始 +150ms、終了 +362ms」)を報告します。
以降は、approved_segments.json の代わりに snapped_segments.json を使用します。
Step 8: PREPARE — クリップの抽出とリフレームの計算
スナップされた各セグメントを、FFmpeg のストリームコピーで抽出します(ほぼ瞬時に完了し、画質は劣化しません)。
$SHORTS_TMP/snapped_segments.json のスナップされた開始時刻と終了時刻を使用します。
ffmpeg -y -ss START -to END -i INPUT_FILE -c copy \
$SHORTS_TMP/clips/clip_01.mp4
各クリップのリフレーム座標を計算します。
python3 "$SHORTS_ROOT/scripts/compute_reframe.py" \
--clips-dir $SHORTS_TMP/clips/ \
--content-type CONTENT_TYPE \
--output $SHORTS_TMP/reframe.json
ユーザーには、抽出したクリップ数、クリップごとのコンテンツタイプ、リフレーム戦略を報告します。
Step 9: Remotion による RENDER
選択したキャプションスタイルを使用して、スナップされたすべてのセグメントをレンダリングします。
node "$SHORTS_ROOT/remotion/render.mjs" \
--segments $SHORTS_TMP/snapped_segments.json \
--reframe $SHORTS_TMP/reframe.json \
--captions $SHORTS_TMP/transcript_cleaned.json \
--style STYLE \
--clips-dir $SHORTS_TMP/clips/ \
--output-dir $SHORTS_TMP/render/
レンダリングスクリプトでは、次の処理を行います。
- Remotion プロジェクトを一度だけバンドルします(約5~10秒)
- 共有の Chrome インスタンスを起動します
- 各セグメントを順番にレンダリングします(各約15~30秒)
- 1080x1920 の MP4 ファイルを出力します
各セグメントのレンダリングが完了するたびに、進捗をユーザーに報告します。
Step 10: EXPORT — プラットフォームに最適化したエンコード
プラットフォームごとに最適化した設定で、レンダリング済みのショート動画をエクスポートします。
bash "$SHORTS_ROOT/scripts/export.sh" \
--input-dir $SHORTS_TMP/render/ \
--platform PLATFORM \
--output-dir ./shorts/
プラットフォームごとのエンコード仕様:
- YouTube Shorts:H.264 High 4.2、12 Mbps、AAC 192k
- TikTok:H.264、CRF 18、-preset slow、AAC 128k
- Instagram Reels:H.264 High 4.2、最大rate 4.5 Mbps、5000k、AAC 128k
- すべて:クリップごとに3種類すべてのバリアントをエクスポートします
NVENC GPU を使用する場合は、h264_nvenc -preset p5 -tune hq により、エンコードを5~10倍高速化できます。
最終的な概要表を提示します。
| # | File | Platform | Duration | Size |
|---|---------------------------|-----------|----------|--------|
| 1 | shorts/short_01_yt.mp4 | YouTube | 39s | 12.3MB |
| 1 | shorts/short_01_tt.mp4 | TikTok | 39s | 8.7MB |
| 1 | shorts/short_01_ig.mp4 | Instagram | 39s | 7.1MB |
エクスポート後の検証: エクスポートしたすべてのファイルを検証します。
bash "$SHORTS_ROOT/scripts/validate.sh" --output-dir ./shorts/
チェック項目:ファイルを再生できること、解像度が1080x1920であること、音声トラックがあり無音ではないこと、ファイルサイズがプラットフォームの制限内であること、動画コーデックがH.264であること、長さが3~90秒であること。 ファイルに問題がある場合は、その内容をユーザーに報告します。問題のあるファイルは、納品前に再レンダリングまたは再エクスポートしてください。
重要なルール
- 処理を始める前に、必ず事前チェックを実行します
- セグメントは必ずユーザーに提示して承認を得ます。確認なしに自動でレンダリングしてはいけません
- 必ずコストを報告します。Remotion のレンダリングは無料(ローカル)で、発生し得るコストは GPU の電力のみです
- エラーには適切に対処します。いずれかの手順に失敗した場合は、エラーを報告し、解決策を提案します
- 成功時はクリーンアップします。エクスポート後に $SHORTS_TMP/ を削除するか、ユーザーに確認します
- ユーザーの選択を尊重します。「再分析」と言われた場合は Step 4 に戻ります
- 抽出にはストリームコピーを使用します。セグメントのカット時に再エンコードしてはいけません(-c copy を使用します)
- レンダリング中の進捗報告では、一度に1つのセグメントを処理します
- 必要に応じて参照資料を読み込みます。Step 4 では scoring-rubric.md、スタイルに関する質問には caption-styles.md を使用します
キャプションスタイルのリファレンス
| スタイル | フォント | 見た目 | 最適な用途 |
|---|---|---|---|
| bold | Montserrat Bold | すべて大文字、ポップイン、アクティブな単語を黄色で表示 | ビジネス、教育、モチベーション |
| bounce | Bangers | 弾むような拡大縮小、明るい色が切り替わる | エンターテインメント、リアクション、エネルギー感 |
| clean | Inter Bold | 最小限のフェードイン、白+シャドウ | プロフェッショナル、落ち着いた雰囲気、インタビュー |
詳細なビジュアル仕様とスプリング設定については、references/caption-styles.md を読み込みます。
設定可能なパラメーター
これらのデフォルト設定は、ほとんどのコンテンツで適切に機能します。ユーザーに特定のニーズがある場合は、代替案を提示してください。
| パラメーター | デフォルト | フラグ/変数 | 変更する場合 |
|---|---|---|---|
| Whisper モデル | large-v3 | --model small | VRAM が少ない場合(6 GB 未満) |
| 画面ズーム | 0.55 | --zoom 0.4 | 画面録画でより広い範囲を表示する場合 |
| カーソル追跡 | 有効 | --no-cursor-track | 画面の内容が静止している場合(スライド、ドキュメント) |
| 無音検出 | 有効 | --no-silence | 処理を高速化する場合、単語境界のみでスナップする場合 |
| スコアのしきい値 | 60 | (SKILL.md の指示) | ハイライトが少ない長尺の動画では低くします |
| セグメントの長さ | 15~55 秒 | (SKILL.md の指示) | プラットフォームごとに調整します(TikTok では 21~34 秒が適しています) |
| 一時ディレクトリ | /tmp/claude-shorts/ | SHORTS_TMP 環境変数 | /tmp の空き容量が限られているシステムの場合 |
| エクスポート先プラットフォーム | all | --platform youtube | 単一のプラットフォームを対象にする場合 |
エラーからの復旧
- 文字起こしに失敗する場合:venv が有効化されていることを確認し、VRAM の使用量を抑えるには
--model smallを試してください - Remotion のレンダリングに失敗する場合:
cd remotion && npm installを確認し、node_modules が存在することを確認してください - エクスポートに失敗する場合:FFmpeg のバージョン(
ffmpeg -version)を確認し、NVENC が失敗する場合は CPU エンコーディングを試してください - ディスク容量が不足している場合:$SHORTS_TMP/ をクリーンアップし、
df -h /tmpで確認してください