video-analysis について
video-analysis はローカル動画ファイルを分析するスキルで、ファイルサイズに応じて動画のネイティブ理解か、フレーム抽出と文字起こしを選びます。提供された動画について質問に答える必要があるエージェント向けです。
主な機能
- 01ファイルサイズに応じたネイティブ・抽出モードの選択
- 02動画対応モデルによる動画分析
- 03間隔またはシーン変化に基づくキーフレーム抽出
- 04Whisper による抽出音声の文字起こし
- 05モデルと抽出上限の設定
活用シーン
- 01提供された動画クリップの内容説明
- 02選択したフレームと文字起こしによる大容量動画の分析
- 03分析コストを抑えるためのフレーム上限調整
- 04動画分析に使うモデルの設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ starchild-ai-agent/ official-skills --skill video-analysisインストール後、Claude Code で/video-analysisを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
analyze.pyconfig.yamlexports.py詳細
動画分析
ネイティブモデル理解またはフレーム抽出 + 文字起こしのいずれかを使用して動画ファイルを分析します。
⚠️ URL 入力 (YouTube / TikTok / IG / Apple Podcasts / Spotify / 任意のリンク) ですか? このスキルはローカルファイルパスを受け取ります。リンクの場合は、メディアをダウンロードしないでください。 入力タイプに応じて順番にルーティングし、テキストが得られた最初のレベルで STOP してください:
- ポッドキャストエピソードのリンクまたはエピソード名 (Apple Podcasts、Spotify、Overcast、
配信元サイト、または単に「X についての a16z のエピソード」) → 配信元のエピソードページ / ショーノート / トランスクリプトページを
web_searchで検索し、次にweb-crawler.scrape_markdown(url)で読み取ります。主要な番組のほとんどはテキストを公開しています。 - 動画 URL →
web-crawler.youtube_video(url)/youtube_transcript(url)(クラウドキャプション、約 1 秒、ダウンロードなし。TikTok にはtiktok_transcriptがあります)。 web_fetchが空で返ってきた (empty_extraction、JS レンダリングページ) → 同じ URL をweb-crawler.scrape_markdownで再試行してください — JS をレンダリングします。 空のプレーン fetch から「トランスクリプトなし」と結論付けないでください。- 何も見つからない → そのとおりに報告して質問してください。ローカルダウンロード +
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.0014 | 8.1s | ~88% | ⭐ デフォルト — 最安 + 最速 |
| google/gemini-3.5-flash | 標準 | ~$0.0152 | 11.8s | ~85% | より詳細、コスト高 |
| qwen/qwen3.6-plus | バジェット | ~$0.0058 | 44.2s | ~95% | 正確だが遅い |
| qwen/qwen3.6-flash | バジェット | ~$0.0027 | 16.6s | ~80% | 被写体を誤読することがある |
| google/gemini-3.1-pro-preview | 標準 | ~$0.0199 | 19.7s | 100% | ベースライン (最高、最も高価) |
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
利用可能な動画モデル
| Model | Alias | Tier | Notes |
|---|---|---|---|
| google/gemini-3.1-flash-lite | flash31 | budget | ⭐ デフォルト、最高の価格/品質 |
| google/gemini-3.5-flash | gemini35 | standard | より詳細、コスト高 |
| google/gemini-3.1-flash-lite | flash31 | budget | 最も安価なオプション |
| google/gemini-3.1-pro-preview | gemini | standard | 最高品質 |
| qwen/qwen3.6-flash | qwenf | budget | 優れた代替案 |
| qwen/qwen3.6-plus | qwen | budget | — |
| minimax/minimax-m3 | mm3 | standard | — |
| meta-llama/llama-4-maverick | maverick | standard | — |
| meta-llama/llama-4-scout | scout | budget | — |
| xiaomi/mimo-v2.5 | mimo | standard | — |
| z-ai/glm-5v-turbo | glm5v | standard | — |
| minimax/minimax-m2.7 | mm27 | budget | 音声のみ、画像なし |
エージェントの動作
ユーザーが(アップロードまたはファイルパス経由で)動画ファイルを提供し、現在の チャットモデルが動画をサポートしていない場合:
analyze_video(path, question)を呼び出します。- 結果モードが
"native"の場合 →result["analysis"]を直接返します。 - 結果モードが
"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 を上げてください |