Communitygithub.com

Tofuswang/video-subtitle-skill

Claude Code スキル: ローカルの Whisper と ffmpeg を使用して動画に字幕を追加します。5★。

video-subtitle-skill とは?

このスキルは、Claude Code エージェントがローカル環境の Whisper 音声認識モデル(mlx-whisper または openai-whisper)と ffmpeg を連携させ、動画に字幕を追加するためのツールです。ユーザーは `/video-subtitle` コマンドを入力するだけで、動画から音声を抽出し、Whisper で文字起こしを行い、SRT 字幕ファイルを生成して動画に焼き付けるまでの全行程を自動化できます。対応プラットフォームは macOS(Apple Silicon 推奨)と Linux で、mlx-whisper は Apple Silicon で高速動作します。スキルは対話式で動作し、言語選択、字幕のクリーンアップ(幻覚除去、固有名詞修正、フラグメント統合)、ffmpeg の libass フィルタの有無に応じた適切な出力方法の選択を自動的に行います。ユーザーは字幕のみの生成(`/video-subtitle srt`)や、既存の SRT を利用した焼き付けのみ(`/video-subtitle burn`)も指定でき、柔軟なワークフローを提供します。

対応✓Claude Code✓Codex CLI~Cursor
npx skills add Tofuswang/video-subtitle-skill

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

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

ドキュメント

/video-subtitle — 動画字幕ツール

ローカルの Whisper モデルを使用して動画音声を SRT 字幕に書き起こし、動画に焼き付けます。

ユーザー呼び出し可能

ユーザーが /video-subtitle と入力したら、このスキルを実行します。

前提条件

このスキルには 2 つのツールが必要です。実行前に利用可能性を確認してください。

1. mlx-whisper(Apple Silicon)または openai-whisper

どちらが利用可能かを検出します:

which mlx_whisper whisper 2>/dev/null

どちらも見つからない場合、ユーザーにいずれかのインストールを案内してください:

  • Apple Silicon Mac(推奨): pip install mlx-whisper
  • 任意のプラットフォーム: pip install openai-whisper

2. ffmpeg(libass 対応)

libass サポートを確認します:

ffmpeg -filters 2>&1 | grep subtitles

出力がない場合(libass がないと subtitles フィルタは利用不可):

  • macOS: brew install ffmpeg-full(keg-only なので /opt/homebrew/opt/ffmpeg-full/bin/ffmpeg を使用)
  • Linux: sudo apt install ffmpeg(通常 libass を含む)
  • 代替: ユーザーが libass なしの通常の ffmpeg しか持っていない場合、焼き付けではなく SRT を字幕トラックとしてソフト埋め込みします。

Whisper モデルの選択

キャッシュされたモデルを確認:

ls ~/.cache/huggingface/hub/ 2>/dev/null | grep whisper

最も大きな利用可能モデルを優先します。何もキャッシュされていない場合:

  • mlx-whisper: mlx-community/whisper-large-v3-mlx
  • openai-whisper: large-v3

モード

  • /video-subtitle path/to/video.mov → フルパイプライン(書き起こし + 修正 + 焼き付け)
  • /video-subtitle srt path/to/video.mov → SRT のみ(書き起こし、焼き付けなし)
  • /video-subtitle burn path/to/video.mov path/to/sub.srt → 焼き付けのみ(既存の SRT を使用)
  • /video-subtitle(引数なし)→ 対話式、動画パスを尋ねます

フルパイプライン

ステップ 1: 動画の確認

パスが指定されていない場合は、AskUserQuestion で尋ねます。ファイルが存在することを確認し、メタデータを読み取ります:

ffmpeg -i "<video_path>" 2>&1 | grep -E "Duration|Stream.*(Video|Audio)"

再生時間、解像度、ファイルサイズをユーザーに報告します。

ステップ 2: 音声抽出

ffmpeg -i "<video_path>" -vn -acodec pcm_s16le -ar 16000 -ac 1 "<output_dir>/<basename>_audio.wav" -y

16kHz モノラル WAV は Whisper に最適な入力形式です。

ステップ 3: 言語の確認

AskUserQuestion でユーザーに尋ねます。一般的なオプション:

言語フラグ
中国語--language zh
英語--language en
日本語--language ja
自動検出--language を省略

ステップ 4: 書き起こし

mlx-whisper:

mlx_whisper --model "<model>" --language <lang> --output-format srt --output-dir "<output_dir>" "<audio_wav>"

openai-whisper:

whisper "<audio_wav>" --model large-v3 --language <lang> --output_format srt --output_dir "<output_dir>"

ユーザーに「書き起こし中です。お待ちください...」と伝えてください。

ステップ 5: SRT のクリーンアップ

生成された SRT を読み取り、以下の修正を行います:

  1. 幻覚除去: 再生時間がゼロのタイムスタンプ(例 00:00:57,640 --> 00:00:57,640)や空のテキストのエントリを削除
  2. 固有名詞修正: Whisper が誤認識しがちなブランド名や技術用語を会話の文脈から修正
  3. フラグメント統合: 0.5 秒未満の短いエントリで意味的につながっているものを結合
  4. 再採番: 以下の Python スニペットを実行してすべてのエントリを再採番:
python3 -c "
import re
with open('<srt_path>', 'r') as f:
    content = f.read()
blocks = re.split(r'\n\n+', content.strip())
out = []
for i, block in enumerate(blocks, 1):
    lines = block.strip().split('\n')
    if len(lines) >= 2:
        lines[0] = str(i)
        out.append('\n'.join(lines))
with open('<srt_path>', 'w') as f:
    f.write('\n\n'.join(out) + '\n')
"

修正した SRT をユーザーに提示し、焼き付け前に追加の編集が必要かどうかを尋ねます。

ステップ 6: 字幕の焼き付け

適切な ffmpeg バイナリを決定します(通常の ffmpeg に libass がない場合は ffmpeg-full を優先):

FFMPEG="ffmpeg"
if ! ffmpeg -filters 2>&1 | grep -q subtitles; then
  if [ -x /opt/homebrew/opt/ffmpeg-full/bin/ffmpeg ]; then
    FFMPEG="/opt/homebrew/opt/ffmpeg-full/bin/ffmpeg"
  fi
fi

その後、焼き付け:

$FFMPEG \
  -i "<video_path>" \
  -vf "subtitles=<srt_path>:force_style='FontSize=24,PrimaryColour=&H00FFFFFF,OutlineColour=&H00000000,Outline=2,MarginV=30'" \
  -c:v libx264 -preset medium -crf 23 \
  -c:a aac -b:a 128k \
  -pix_fmt yuv420p \
  "<output_dir>/<basename>_subtitled.mp4" -y

force_style オプション:

パラメータデフォルト説明
FontSize24フォントサイズ
PrimaryColour&H00FFFFFF白文字
OutlineColour&H00000000黒い輪郭
Outline2輪郭の太さ
MarginV30下端余白

重要: SRT ファイルのパスに ffmpeg のフィルタパーサーを混乱させる特殊文字が含まれていないことを確認してください。必要に応じて相対パスまたはシンボリックリンクを使用してください。

ステップ 7: 完了

出力ファイルのパスとサイズを報告します。open <path> でプレビューするよう提案します。中間ファイル _audio.wav は削除可能であることをユーザーに通知します。


トラブルシューティング

問題原因解決策
No such filter: 'subtitles'ffmpeg に libass がないffmpeg-full を使用するか libass をインストール
No such filter: 'drawtext'ffmpeg に libfreetype がないffmpeg-full を使用
SRT エントリの重複/空Whisper の幻覚ステップ 5 でクリーンアップ
中国語の文字が四角く表示されるCJK フォントがないmacOS: 自動で PingFang にフォールバック。Linux: apt install fonts-noto-cjk
Error parsing filterchainSRT パスに特殊文字相対パスを使い、スペースを避ける

品質ルール

  • 忠実な書き起こし: 実際に話された内容のみを書き起こし、意味を追加したり書き換えたりしない
  • 固有名詞の修正: よくある Whisper の誤認識を修正するが、ユーザーに確認する
  • 字幕のリズム: 1 エントリあたり最大 2 行、1 行あたり CJK 文字最大約 20 文字
  • 後片付け: 完了後、中間ファイル(_audio.wav)を削除するようユーザーに通知する

関連スキル