mcpField
V
video-analysis

video-analysis

github.com/starchild-ai-agentクリエイティブ・メディア301.8k 回インストール6 日前に更新
リポジトリ

video-analysis について

video-analysis はローカル動画ファイルを分析するスキルで、ファイルサイズに応じて動画のネイティブ理解か、フレーム抽出と文字起こしを選びます。提供された動画について質問に答える必要があるエージェント向けです。

主な機能

  1. 01ファイルサイズに応じたネイティブ・抽出モードの選択
  2. 02動画対応モデルによる動画分析
  3. 03間隔またはシーン変化に基づくキーフレーム抽出
  4. 04Whisper による抽出音声の文字起こし
  5. 05モデルと抽出上限の設定

活用シーン

  1. 01提供された動画クリップの内容説明
  2. 02選択したフレームと文字起こしによる大容量動画の分析
  3. 03分析コストを抑えるためのフレーム上限調整
  4. 04動画分析に使うモデルの設定

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/starchild-ai-agent/official-skills --skill video-analysis

インストール後、Claude Code で/video-analysisを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

analyze.py
config.yaml
exports.py

詳細

動画分析

ネイティブモデル理解またはフレーム抽出 + 文字起こしのいずれかを使用して動画ファイルを分析します。

⚠️ URL 入力 (YouTube / TikTok / IG / Apple Podcasts / Spotify / 任意のリンク) ですか? このスキルはローカルファイルパスを受け取ります。リンクの場合は、メディアをダウンロードしないでください。 入力タイプに応じて順番にルーティングし、テキストが得られた最初のレベルで STOP してください:

  1. ポッドキャストエピソードのリンクまたはエピソード名 (Apple Podcasts、Spotify、Overcast、 配信元サイト、または単に「X についての a16z のエピソード」) → 配信元のエピソードページ / ショーノート / トランスクリプトページを web_search で検索し、次に web-crawler.scrape_markdown(url) で読み取ります。主要な番組のほとんどはテキストを公開しています。
  2. 動画 URL → web-crawler.youtube_video(url) / youtube_transcript(url) (クラウドキャプション、約 1 秒、ダウンロードなし。TikTok には tiktok_transcript があります)。
  3. web_fetch が空で返ってきた (empty_extraction、JS レンダリングページ) → 同じ URL を web-crawler.scrape_markdown で再試行してください — JS をレンダリングします。 空のプレーン fetch から「トランスクリプトなし」と結論付けないでください。
  4. 何も見つからない → そのとおりに報告して質問してください。ローカルダウンロード + analyze_video() は、ユーザーがメディアのダウンロードを明示的に依頼した場合、 またはファイルを渡してきた場合にのみ実行されます。これはフォールバックではありません: データセンターの IP は ボットチェックに引っかかり、100 MB の音声取得には数分かかり、たいてい失敗します。

トランスクリプトのテキストは発話のみです — それだけから話者を特定しないでください (web-crawler のメタデータ優先ルールを参照)。

仕組み

analyze_video(path, question)
      │
      ├─ file_size ≤ threshold (default 20MB)
      │     → Send video to a supports_video model (default Gemini 3.1 Flash Lite)
      │     → Model sees full video natively (best quality)
      │
      └─ file_size > threshold
            → ffmpeg extracts keyframes (scene detection for long videos)
            → Whisper transcribes audio track
            → Returns frame image paths + transcript text
            → Agent feeds these to the current chat model

クイックスタート

⚠️ 呼び出し — ドット付きインポートを使用しないでください。 ディレクトリ名に ハイフン (video-analysis) が含まれるため、from skills.video-analysis.exports import ... は Python の構文エラーになります (- がマイナスとして解析されます)。これはこのスキルだけでなく、 ハイフンを含むすべてのスキルに当てはまります。以下の 2 つのパターンのいずれかを使用してください。

パターン A — ワークスペースルートから (スクリプトに推奨):

cd /data/workspace/skills/video-analysis && \
  python3 -c "from exports import analyze_video; \
    import json; \
    print(json.dumps(analyze_video('output/videos/clip.mp4', \
      question='What happens in this video?'), ensure_ascii=False))"

注: スキルディレクトリに cd した場合でも、動画パスはワークスペース相対で渡してください (analyze.py は WORKSPACE_DIR を基準に解決します)。

パターン B — starchild-clawd スクリプト内:

from core.skill_tools import video_analysis
result = video_analysis.analyze_video("output/videos/clip.mp4",
                                      question="What happens in this video?")

❌ しないでください: exec(open('skills/video-analysis/analyze.py').read()) — analyze.py は インポート時に __file__ を使用しますが、これは exec では未定義であるため、クラッシュします。 上記のどちらのパターンも避けなければならない場合は、importlib.util.spec_from_file_location を使用して ファイルパスで読み込んでください。

# result keys (same for both patterns):
# Analyze a video — auto-selects native or extraction mode
# result = analyze_video("output/videos/clip.mp4", question="What happens in this video?")

# result keys:
#   success: bool
#   mode: "native" | "extraction"
#
# If mode == "native":
#   analysis: str (model's text response)
#   model: str (which model was used)
#   tokens: {input, output, video, audio}
#
# If mode == "extraction":
#   frame_paths: list[str] (workspace-relative paths to keyframe JPEGs)
#   transcript: str | None (Whisper transcription text)
#   frame_count: int
#   duration_sec: float

エクスポートの使用

from core.skill_tools import video_analysis

# Full analysis (auto-selects mode)
result = video_analysis.analyze_video("output/videos/my_video.mp4", question="Describe this video")

# Check current config
config = video_analysis.get_config()

# Get video metadata without analyzing
info = video_analysis.get_video_info("output/videos/my_video.mp4")
# → {"duration": 45.2, "size": 12345678, "width": 1920, "height": 1080, "has_audio": true}

ネイティブモード (小さい動画)

サイズしきい値を下回る動画の場合、このスキルは動画全体をネイティブ動画入力をサポートするモデルに送信します。 モデルはすべてのフレームを見て、音声を聞きます。

デフォルトモデル: google/gemini-3.1-flash-lite — 動画に対して最高の価格/品質。

モデルベンチマーク (6MB のクリップ、gemini-3.1-pro-preview ベースラインとの比較):

モデルティアコスト時間精度備考
google/gemini-3.1-flash-liteバジェット~$0.00148.1s~88%⭐ デフォルト — 最安 + 最速
google/gemini-3.5-flash標準~$0.015211.8s~85%より詳細、コスト高
qwen/qwen3.6-plusバジェット~$0.005844.2s~95%正確だが遅い
qwen/qwen3.6-flashバジェット~$0.002716.6s~80%被写体を誤読することがある
google/gemini-3.1-pro-preview標準~$0.019919.7s100%ベースライン (最高、最も高価)

flash-lite は、シーン全体、アクションの流れ、トランジションを正しく識別し、 Pro ベースラインより約 14 倍低いコストで済みます。最大限の精度 (正確なキャラクター名、細部) が必要な場合は、config/video-analysis.yaml の default_model を gemini-3.1-pro-preview または gemini-3.5-flash に切り替えてください。

抽出モード(大きな動画)

サイズのしきい値を超える動画の場合、スキルはキーフレームを抽出し、音声を文字起こしします:

  • 短い動画(60秒以下): N 秒ごとに 1 フレーム(デフォルト:2 秒)
  • 長い動画(60秒超): シーン変更検出により、視覚的に異なるフレームを選択
  • 音声: 抽出され、文字起こしのために Whisper に送信されます
  • 最大フレーム数: コストを抑えるため 30 に制限(設定可能)

エージェントはフレーム画像のパスと文字起こしテキストを受け取り、それらを 画像添付+コンテキストテキストとして現在のチャットモデルに渡します。

設定

カスタマイズするには(ワークスペース内の)config/video-analysis.yaml を編集します。このファイルは 初回使用時に自動的に作成され、上書きしたいキーのみが必要で、スキルの更新後も維持されます。

skills/video-analysis/config.yaml は編集しないでください — これは出荷時のデフォルトであり、 スキルの自動更新のたびに上書きされます。ユーザーファイルはその上に重ねられます。

スタンドアロンのスキルとチャットの「動画を送信」フローの両方がこの同じ設定を読み込むため、 1 か所の編集でどこでもモデルが変わります。利用可能なキー:

# Model for native video understanding
default_model: google/gemini-3.1-flash-lite

# Size threshold: native (≤) vs extraction (>)
# Set to 0 → always extraction. Set to 100 → always native.
native_size_limit_mb: 20

# Frame extraction settings
extraction:
  max_frames: 30                  # Max keyframes to extract
  short_video_interval_sec: 2     # Frame interval for ≤60s videos
  scene_threshold: 0.3            # Scene detection sensitivity (0.0-1.0)
  transcribe_audio: true          # Whether to Whisper-transcribe audio
利用可能な動画モデル
ModelAliasTierNotes
google/gemini-3.1-flash-liteflash31budget⭐ デフォルト、最高の価格/品質
google/gemini-3.5-flashgemini35standardより詳細、コスト高
google/gemini-3.1-flash-liteflash31budget最も安価なオプション
google/gemini-3.1-pro-previewgeministandard最高品質
qwen/qwen3.6-flashqwenfbudget優れた代替案
qwen/qwen3.6-plusqwenbudget—
minimax/minimax-m3mm3standard—
meta-llama/llama-4-maverickmaverickstandard—
meta-llama/llama-4-scoutscoutbudget—
xiaomi/mimo-v2.5mimostandard—
z-ai/glm-5v-turboglm5vstandard—
minimax/minimax-m2.7mm27budget音声のみ、画像なし

エージェントの動作

ユーザーが(アップロードまたはファイルパス経由で)動画ファイルを提供し、現在の チャットモデルが動画をサポートしていない場合:

  1. analyze_video(path, question) を呼び出します。
  2. 結果モードが "native" の場合 → result["analysis"] を直接返します。
  3. 結果モードが "extraction" の場合 → result["frame_paths"] を画像 参照として、result["transcript"] をコンテキストとして使用し、フレーム+文字起こしに基づいて 現在のモデルに分析を依頼します。

現在のモデルが動画をサポートしている場合、バックエンドはフェーズ 1(base64 コンテンツブロックの注入)を通じて ネイティブに処理します — このスキルは不要です。

トラブルシューティング

問題対処
「ファイルが見つかりません」パスがワークスペース相対であることを確認してください(例:output/videos/x.mp4)
ネイティブモードがエラーを返すconfig/video-analysis.yaml の default_model が有効であることを確認してください
音声の文字起こしがない動画に音声トラックがない可能性があります。結果の has_audio を確認してください
抽出されるフレームが少なすぎるconfig/video-analysis.yaml の scene_threshold を下げてください(例:0.15)
フレームが多すぎる / コストが高いmax_frames を減らすか、scene_threshold を上げてください

コメント