ビデオ分析 – 見えているもの、言われていること は何をしますか?
あなたは動画や音声を直接入力できません。あなたが読むのは、動画から抽出された画像と、その音声の文字起こしです。以下の手順で、動画をこれら2つの要素に変換し、過剰な主張をせずに読み取る方法を説明します。
出力先 – 厳守ルール
抽出されたすべての素材は、動画と同じフォルダ内の1つの作業フォルダに配置します:
<動画のフォルダ>\<動画ファイル名>.analysis\ — スクラッチパッド、テンポラリディレクトリ、プロジェクトフォルダには絶対に配置しないでください。
このフォルダは、その動画の作業が完了したら所有者が削除し、ディスク容量を回収します。
自分で削除しないでください。 クリーンアップを依頼された場合は、trash スキルを使用してそのフォルダを正確にゴミ箱に移動します(rm ではなく、常にゴミ箱を使用)。あなたが作成した分析レポート(成果物)は、プロジェクトが指定する場所に配置すべきであり、.analysis フォルダ内には配置しないでください。これにより、フォルダをゴミ箱に移しても価値ある情報が失われることはありません。
1. ツールのセットアップ(各マシンで1回)
python ~/.claude/skills/video-analysis/scripts/setup_tools.py --check # インストール状況の確認
python ~/.claude/skills/video-analysis/scripts/setup_tools.py # 不足しているものをインストール
pip --user を使用して以下をインストールします:imageio-ffmpeg(ffmpegバイナリをバンドル — システムffmpeg、管理者権限、winget/chocoは不要)、Pillow、numpy、faster-whisper。また、Whisper small モデルをキャッシュします(これが唯一のネットワークアクセスです。以後はすべてオフライン)。終了コード 0 = READY です。
セルフテスト(合成動画、9つのチェック、--full でWhisperを追加):
python ~/.claude/skills/video-analysis/scripts/selftest.py
2. 抽出
python ~/.claude/skills/video-analysis/scripts/extract_video.py "<動画パス>" --language ja
数分以上の動画の場合はバックグラウンドで実行してください。文字起こしはCPU上で実時間の約5倍の速度で処理されます(15分の動画で約3分)。オプション:--interval 5(フレーム間の秒数。動きの速い画面には2、講演者には10〜15)、--model small(medium = より高精度だが3倍遅い)、--skip-frames、--skip-transcript、--at HH:MM:SS[.mmm](繰り返し指定可能。指定した瞬間のフル解像度フレームを取得 — 手順3dで使用)。
<動画>.analysis\ 内に以下を生成します:frames\(指定間隔ごとのフレーム)、sheets\(3x3のコンタクトシート。各画像にmm:ssが黄色でスタンプ)、keyframes.txt + keysheets\(視覚的に変化したフレームのみ — スライド/画面切り替え)、audio.wav、transcript.txt([mm:ss] テキスト) + transcript.json、at\、manifest.json。再実行すると、完了したステージをスキップして再開します。パラメーターを変更した場合や異なる動画の場合は、出力を混在させずに**拒否(終了コード3)**します。終了コード1 = 処理失敗、2 = 不正な入力。
3. 読み取り – この順序で
a. まず文字起こし全体を読みます(transcript.txt)。コースやデモでは、決定的な内容(数値、ルール、例外、実際の方法)は、画面ではなく音声に含まれていることが非常に多いです。
b. キーフレームのシート(keysheets\)を確認し、それぞれ異なるスライド/画面を1回ずつ見ます。
c. コンタクトシート(sheets\) — すべてを順番に確認し、キーフレーム間で何が動いているか(カーソル、描画、更新されるチャート)を追います。
d. 音声が指し示す場所を拡大:話者が「ここ」「このキャンドル」「…を見てください」などと言った場合、最初の実行時と同じオプションで --at <タイムスタンプ> を指定して再実行します(そうしないとマニフェストチェックで終了コード3で拒否されます)。その後、そのフル解像度のフレームを読み取ります。シートは1セル640ピクセルで、チャートのラベルや小さなテキストには小さすぎます。
e. 分析を記述します(手順4)。
4. レポート – 3つの要素を区別する
各箇所について、タイムスタンプを引用し、すべての記述を以下のいずれかに分類します:
- ON SCREEN(画面表示) — 画像が実際に示しているもの(スライドテキスト、チャート、注釈、UI)。
- SAID(発言) — 音声が述べているもの(引用または近い言い換え、
[mm:ss]付き)。 - INFERENCE(推論) — これら2つを結びつけるあなたの解釈。決して「見えた」または「聞こえた」として提示しないでください。
常に以下を含めてください:
- 書かれていることと言われていることの間のギャップ(例:スライドにはあることが書いてあるが、音声で実際に重要なルールが追加されている、または矛盾している場合)。
- 1回だけ示されているもの(デモの1回の例示は説明であり、根拠ではありません)。
- 限界:フレームはN秒ごとにサンプリングされており、短時間のイベントを見逃す可能性があります。フレームのタイムスタンプはインデックス×間隔で近似値です(± 間隔の半分、可変フレームレートの録画ではさらに大きくなります)。キーフレームの重複除去により小さな編集が隠れる可能性があります。Whisperは名前や専門用語のスペルを誤ることがあります(画像と照合してください)。トーン、感情、音楽、話者の識別、動きの信頼性の高い読み取りはできません。
5. 作業後
ユーザーに作業フォルダのパスとサイズを伝えます(抽出の最後に表示されます)。ユーザーが動画の作業が完了したと言うまでそのままにしておきます。その後、trash スキルを使用してゴミ箱に移動します。
既知の落とし穴(スクリプトで既に対処済み)
faster_whisperのmodel.transcribe("<パス>")は、新しいPyAVでTypeError: open() got an unexpected keyword argument 'metadata_errors'を発生させます。スクリプトはffmpegで16kHzモノラルPCM16のWAVを抽出し、代わりにfloat32配列を渡します。imageio-ffmpegはffmpegを同梱していますが、ffprobeは含まれていません。再生時間とオーディオの有無は、ffmpeg自身のバナーから読み取ります。select='gt(scene,N)'+showinfoを使用したシーン検出は、-loglevel errorでは何も出力しません。代わりにキーフレームはサムネイルの差分を使用します。