mcpField
W
watch

watch

github.com/taoufik123-collabクリエイティブ・メディア1.1k151 回インストール14 週間前に更新
リポジトリ

watch について

動画 URL やローカル動画を分析する Claude スキルです。抽出したフレーム、タイムスタンプ付き文字起こし、編集テンポの指標を組み合わせ、Obsidian のナレッジベースが見つかった場合は取り込み用レポートを準備します。

主な機能

  1. 01シーン変化に応じたフレーム抽出
  2. 02Whisper による補完付き文字起こし
  3. 03編集テンポの指標
  4. 04冒頭 10 秒の詳細分析
  5. 05Obsidian 取り込み向けの構造化レポート

活用シーン

  1. 01動画の要約と質問への回答
  2. 02指定した時点や区間の確認
  3. 03冒頭のフックと編集テンポの分析
  4. 04Obsidian ナレッジベース用レポートの作成

インストール

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

$npx skills add https://github.com/taoufik123-collab/claude-watch --skill watch

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

同梱ファイル

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

README.md
.gitattributes
.gitignore
AUTHORS.md
LICENSE
CHANGELOG.md
.claude-plugin/
marketplace.json
plugin.json
.codex-plugin/
plugin.json
.github/workflows/
release.yml
commands/
watch.md
hooks/
hooks.json
hooks/scripts/
check-setup.sh
scripts/
hook.py
pacing.py
download.py
report.py
build-skill.sh
frames.py
setup.py
watch.py
whisper.py
transcribe.py
scripts/tests/
__init__.py
test_report.py
test_pacing.py
test_frames_scene.py

詳細

/watch — Claude が動画を視聴します

動画入力がなくても、このスキルを使えば動画を扱えます。Python スクリプトが動画をダウンロードし、シーンチェンジで検出したショットごとに 1 枚の JPEG フレームを抽出し、タイムスタンプ付きの文字起こしを取得します(まずネイティブ字幕を使い、利用できない場合は Whisper API を使用します)。さらに、編集上のテンポに関する指標を算出し、最初の 10 秒をより高密度で詳しく分析します。次に各フレームのパスを Read して画像を確認し、文字起こしと組み合わせてユーザーに回答し、構造化された report.md に記入してから、分析を Taoufik の Second Brain に取り込むか尋ねます。

v2 での変更点

  • シーンチェンジによるフレームサンプリング — 均等な間隔ではなく、検出したショットごとに 1 フレームをサンプリングします。長い動画でのフレーム数を抑えながら、すべての切り替わりを捉えます。
  • 編集上のテンポ指標 — カット数/分、平均ショット長、動き(利用可能な場合)を算出します。編集者のような観点でテンポを分析できます。
  • 冒頭の詳細分析 — 最初の 10 秒を自動的に 2 fps と単語単位の Whisper で処理します。動画の中でも特に効果の高い 10 秒を、きめ細かく分析します。
  • 構造化された report.md — 各視聴で、取り込みに適した形式のレポートを <workdir>/report.md に出力します。内容は TL;DR、重要な場面、冒頭の内訳、編集プロファイル、引用に適した場面、エンティティ、概念、文字起こしです。ナラティブ部分は `` マーカー付きで出力されます。取り込みを提案する前に、これらを記入してください。
  • ステップ 4.5 — 取り込み確認 — ユーザーへの回答後、Obsidian の保管庫に取り込むか一度だけ尋ねます。「これを Obsidian の保管庫に取り込みますか?」保管庫が検出され、ユーザーが希望した場合は、$VAULT_DIR/CLAUDE.md(存在する場合)を読み、その保管庫の Ingest op を実行してレポートを取り込みます。

上記の追加によって新たな依存関係が増えることはありません。ffmpeg と標準ライブラリ、既存の Whisper バックエンドだけを使用します。

設定 — ユーザーの Obsidian 保管庫の検出

ステップ 4.4 と 4.5 では、ユーザーがほかの情報と同じ場所で読めるよう、Obsidian 保管庫内にレポートを配置します。以下の順に保管庫のディレクトリを解決します。最初に見つかったパスを使用し、以降の説明ではそのパスを $VAULT_DIR とします。

  1. $WATCH_VAULT_DIR 環境変数 — 設定されていて、そのパスが存在する場合は使用します。これはユーザーが指定する上書き設定です。
  2. ~/Second brain/ — ディレクトリとして存在する場合。
  3. ~/Documents/Obsidian/ — ディレクトリとして存在する場合。
  4. ~/Obsidian/ — ディレクトリとして存在する場合。
  5. 見つからない場合 — ステップ 4.4 と 4.5 を完全にスキップします。状況が分かるように、チャットに次の 1 行を表示します。📄 Report (no vault detected): <workdir>/report.md 自動取り込みを希望する場合は、WATCH_VAULT_DIR の設定を提案します。

スキル内で bash を使って手早くパスを解決する方法は次のとおりです。

VAULT_DIR="${WATCH_VAULT_DIR:-}"
if [ -z "$VAULT_DIR" ] || [ ! -d "$VAULT_DIR" ]; then
  for candidate in "$HOME/Second brain" "$HOME/Documents/Obsidian" "$HOME/Obsidian"; do
    if [ -d "$candidate" ]; then VAULT_DIR="$candidate"; break; fi
  done
fi

ステップ 4.4 の obsidian:// URL スキームで使う保管庫の URL 名は、パスの最後の要素です。たとえば、$HOME/Second brain の場合は Second brain です。スペースは %20 に URL エンコードします。

ステップ 0 — セットアップの事前確認(/watch の実行ごとに実行、成功時は無表示)

Python インタープリター: このスキル内のすべての python3 ... コマンドは macOS/Linux 向けです。Windows では python に置き換えてください。Windows の python3 コマンドは Microsoft Store のスタブであり、スクリプトを実行できません。

/watch を実行する前に、依存関係と API キーが設定されていることを確認します。

python3 "${CLAUDE_SKILL_DIR}/scripts/setup.py" --check

これは 100ms 未満で完了する確認です。終了コードが 0 の場合、スクリプトは何も出力しません。そのまま何も言わずにステップ 1 に進んでください。ユーザーに「セットアップが完了しました」と伝えてはいけません。毎回のターンでステータスメッセージを伝える必要はありません。ステップ 0 でユーザーに表示してよいのは、対処が必要な場合のみです。

終了コードが 0 以外の場合は、次の表に従ってください。

終了コード意味対処
2バイナリ(ffmpeg / ffprobe / yt-dlp)が不足していますインストーラーを実行します
3Whisper API キーがありませんインストーラーを実行して .env を作成し、その後ユーザーにキーを尋ねます
4両方とも不足していますインストーラーを実行し、その後キーを尋ねます

インストーラーは冪等で、再実行しても安全です。

python3 "${CLAUDE_SKILL_DIR}/scripts/setup.py"

Homebrew を使用している macOS では、ffmpeg と yt-dlp が自動的にインストールされます。Linux/Windows では、ユーザーが実行するための正確なインストールコマンドが表示されます。コメント付きのプレースホルダーを含む ~/.config/watch/.env をパーミッション 0600 で作成し、依存関係とキーが揃うと SETUP_COMPLETE=true を書き込みます。これにより、次のセッションで、このユーザーがすでにウィザードを完了していることがわかります。

インストール後も API キーが不足している場合: AskUserQuestion を使用して、ユーザーが Groq API キー(推奨:より安価で高速)または OpenAI キーを持っているか尋ねます。その後、~/.config/watch/.env に書き込み、対応する GROQ_API_KEY=... または OPENAI_API_KEY=... の行を設定します。Whisper のセットアップを希望しない場合は、--no-whisper を指定して続行し、ネイティブ字幕のない動画はフレームのみになることを伝えてください。

構造化モード(任意): python3 "${CLAUDE_SKILL_DIR}/scripts/setup.py" --json は、{status, first_run, missing_binaries, whisper_backend, has_api_key, config_file, platform} を出力します。status は ready | needs_install | needs_key | needs_install_and_key のいずれかです。具体的な条件で分岐する必要がある場合(例:「これがユーザーにとって初めての実行か?」→ first_run: true)に使用してください。

同一セッション内では、後続の /watch 呼び出しでステップ 0 を省略できます。--check が 0 を返した後は、ターン間で環境に変化はありません。

使用する場面

  • ユーザーが動画の URL(YouTube、Vimeo、X、TikTok、Twitch のクリップ、yt-dlp がサポートするほとんどのサイト)を貼り、その動画について質問した場合。
  • ユーザーがローカルの動画ファイル(.mp4、.mov、.mkv、.webm など)を指定し、その動画について質問した場合。
  • ユーザーが /watch <url-or-path> [question] と入力した場合。

推奨制限

  • 精度を重視する場合は、10 分未満の動画が最適です。 フレームのカバー範囲は動画の長さに反比例します。
  • 上限は合計 100 フレーム、2 fps です。 フレーム数に応じてトークンコストが増加するため、スクリプトは動画の長さに応じたフレーム予算を目標にします(予算から 2 fps を超える計算になっても、2 fps を超えることはありません)。
    • ≤30s → 約 1~2 fps(最大 30 フレーム)
    • 30s-1min → 約 40 フレーム
    • 1-3min → 約 60 フレーム
    • 3-10min → 約 80 フレーム
    • >10min → 100 フレームをまばらに配置(警告を表示)
  • ユーザーから長い動画を渡された場合は、まばらなスキャンにトークンを使う前に、特定の区間を見たいかどうか尋ねることを検討してください。

呼び出し方法

ステップ 1 — ユーザーの入力を解析します。 動画のソースと、ユーザーが尋ねた質問を分けます。質問(またはユーザーが以前に述べた関心事)が意図です。--intent を使ってスクリプトに渡してください。例:/watch https://youtu.be/abc what's the hook pattern? → source = https://youtu.be/abc、intent = what's the hook pattern?。質問がない場合は、レポートの TL;DR に視点を持たせるため、「全般的な要約」のような簡潔な推定意図を指定してください。意図はステップ 4 でレポートの TL;DR とエンティティ/概念のセクションに反映されます。同じ動画でも、意図が「価格設定の戦術」か「編集スタイル」かによって、レポートの内容は異なります。

ステップ 2 — watch スクリプトを実行します。 ソースはそのまま渡してください。通常の引用符で囲む以外に、自分でシェル用のエスケープを追加しないでください。

python3 "${CLAUDE_SKILL_DIR}/scripts/watch.py" "<source>" --intent "<intent string>"

ユーザーがこの動画を見たい理由について何らかの手がかりがある場合は、必ず --intent を渡してください。手がかりには、ユーザーの質問、明示された目標、簡潔に推定した要約が含まれます。--intent を空にしても動作しますが、レポートの各セクションがユーザーの意図に沿いにくくなります。

オプションのフラグ:

  • --start T / --end T — セクションに絞り込みます。SS、MM:SS、HH:MM:SS を指定できます。どちらかを設定すると、fps が自動的に高密度になります(下記の「セクションに絞り込む」を参照)。
  • --max-frames N — トークン予算を抑えるために上限を下げます(例:--max-frames 40)。
  • --resolution W — フレーム幅を px 単位で変更します(デフォルトは 512。画面上のテキストを読む必要がある場合に限り 1024 に上げてください)。
  • --fps F — 自動 fps を上書きします(上限は 2 fps)。--fps を設定すると、シーン変化のサンプリングが無効になります。
  • --out-dir DIR — 作業ファイルの保存先を指定します(デフォルトは自動生成される一時ディレクトリ)。
  • --whisper groq|openai — 使用する Whisper バックエンドを指定します(デフォルトでは、両方のキーがある場合は Groq を優先します)。
  • --no-whisper — Whisper によるフォールバックを完全に無効にします(字幕がない場合はフレームのみ)。
  • --no-scene-change — 均一なフレームサンプリングを強制します(デバッグ専用。通常は有効のままにしてください)。
  • --no-hook-microscope — 0〜10 秒の高密度パスを省略します(Whisper の呼び出しを約 1 回節約します)。
セクションに絞り込む(フレームレートを上げる)

ユーザーが特定の場面について尋ねた場合(「2 分の時点で何が起きますか?」「0:45 から 1:00 にズームインして」「最初の 10 秒」など)は、--start や --end を渡してください。スクリプトは、動画全体の予算よりも高密度な、絞り込みモードの予算に切り替えます(ただし上限は 2 fps です)。

  • ≤5 秒 → 2 fps(最大 10 フレーム)
  • 5〜15 秒 → 2 fps(最大 30 フレーム)
  • 15〜30 秒 → 約 2 fps(最大 60 フレーム)
  • 30〜60 秒 → 約 1.3 fps(最大 80 フレーム)
  • 60〜180 秒 → 約 0.6 fps(100 フレーム、上限あり)

絞り込みモードが適しているのは、次のような場合です。

  • ユーザーが明示的に指定した場面や範囲(「2:30 あたり」「イントロ」「最後の 30 秒」など)。
  • 動画が約 10 分を超え、ユーザーの質問が特定の部分に関する場合。動画全体をまばらにスキャンするより、該当箇所に絞り込んで実行するほうがはるかに役立ちます。
  • 全体をスキャンした後、特定の範囲について十分な詳細が得られなかったため、再実行する場合。

文字起こしは同じ範囲に自動的に絞り込まれます。フレームのタイムスタンプは絶対時間です(開始位置からの相対時間ではなく、実際の動画の時間軸に沿ったものです)。

例:

# Last 10 seconds of a 1 minute video
python3 "${CLAUDE_SKILL_DIR}/scripts/watch.py" video.mp4 --start 50 --end 60

# Zoom into 2:15 → 2:45 at 3 fps (90 frames)
python3 "${CLAUDE_SKILL_DIR}/scripts/watch.py" "$URL" --start 2:15 --end 2:45 --fps 3

# From 1h12m to the end of the video
python3 "${CLAUDE_SKILL_DIR}/scripts/watch.py" "$URL" --start 1:12:00

ステップ 3 — スクリプトに表示されたすべてのフレームパスを読み込みます。 Read ツールは JPEG を画像として直接表示します。すべてのフレームを 1 回のメッセージで読み込み(並列ツール呼び出し)、まとめて確認してください。フレームは時系列順に並んでおり、t=MM:SS のタイムスタンプが付いているため、文字起こしと照らし合わせることができます。

ステップ 4 — ユーザーに回答してから、レポートを作成します。 ここまでに、3 つの情報源が揃っています。

  • フレーム — 各タイムスタンプで画面に表示されている内容
  • 文字起こし — 各タイムスタンプで話されている内容
  • report.md — `` マーカーを含む、<workdir>/report.md にある構造化された成果物

まず、タイムスタンプを引用して、チャットでユーザーの質問に回答します。 次に、Edit ツールを使って report.md の保留中マーカーを埋めてください。`` をすべて順番に確認します。

  • TL;DR — ユーザーの意図(フロントマターから読み取る)に沿って、3〜5個の箇条書き
  • Key moments — タイムスタンプ付きの箇条書き、5〜10個
  • Hook microscope interpretation — フレームごとに、視覚的な変化 × 発言内容を記述し、フックのパターン(質問、逆張りの主張、イン・メディアス・レス、デモ先行など)を特定
  • Editorial profile fingerprint — ペース配分の数値とヒーローフレームから推測した、スタイルの要約を一行で記述
  • Quotable moments — トランスクリプトから、単独で引用できる印象的なセリフを上位3〜5個
  • Entities mentioned — 人物、企業、ツール、場所を、wiki/entities/ のスラッグ形式(ケバブケース、小文字)で記述。[[wikilink]] 形式を使用
  • Concepts surfaced — フレームワーク、メンタルモデル、名前の付いたパターンを、それぞれ簡潔に説明

すべて入力済みの report.md が Step 4.5 で取り込まれます。入力を省略しないでください。マーカーが空のままだと、正しく取り込まれません。

Step 4.4 — Obsidian vault が検出された場合、そこにステージングして Obsidian で開く。 すべてのマーカーを埋めた後、Configuration セクションに従って $VAULT_DIR を解決します。vault が検出されない場合はこのステップをスキップし、チャットに 📄 Report (no vault detected): <workdir>/report.md を出力します。

$VAULT_DIR が解決された場合:

  1. ここでスラッグを導出します(Step 4.5 まで待たないでください)。report.md のフロントマターから動画タイトルを取得し、スラッグ化します(小文字、ASCII 文字のみ、ハイフン区切り、最大60文字)。その後に -YYYY-MM-DD を追加します。例:karpathy-claude-md-43k-installs-2026-05-24。
  2. ステージングディレクトリを作成します: mkdir -p "$VAULT_DIR/raw/watched/<slug>"。
  3. report.md とすべてのヒーローフレームをコピーします(ファイル名はレポートのフロントマターにある hero_frames: を参照)。レポートを Obsidian で開けるよう、必ず vault 内に配置してください。
  4. URL スキーム経由で Obsidian で開きます(macOS)。vault の URL 名は $VAULT_DIR の最後の要素で、スペースは %20 に URL エンコードします:
    VAULT_NAME=$(basename "$VAULT_DIR" | sed 's/ /%20/g')
    open "obsidian://open?vault=${VAULT_NAME}&file=raw/watched/<slug>/report.md"
    
    file= の値は vault ルートからの相対パスで、先頭にスラッシュを付けません。許可を求めないでください。ユーザーは /watch を実行することで、すでに同意しています。
  5. vault からの相対パスをチャットに一行で出力します: 📄 Report (open in Obsidian): raw/watched/<slug>/report.md。Obsidian が閉じていた、または URL ハンドラーが機能しなかった場合でも、ユーザーは vault 内から手動で移動できます。

理由:レポートは /watch の重要な活用ポイントです。ユーザーが Obsidian ですべて読む場合、Preview や VS Code で開くと目的に反します。Step 4.4 でステージングしておけば、Step 4.5 の「Yes / Stage」ではコピー処理が不要になります(ファイルはすでに vault 内にあります)。異なるのは Ingest 処理を実行するかどうかだけです。

Step 4.5 のクリーンアップに関する注意: 4.5 でユーザーが「No, drop it」を選び、かつ 4.4 で vault にステージング済みの場合は、事前にステージングしたため、rm -rf "$VAULT_DIR/raw/watched/<slug>" も実行してください。「Yes」または「Stage」を選んだ場合は、vault 内のコピーを削除しないでください。

Step 4.5 — Obsidian vault への取り込みを提案します。 Step 4.4 で vault が検出されなかった場合は、このステップ全体をスキップします。 それ以外の場合は、AskUserQuestion を一度使用して、次の選択肢を提示します(vault が見つかった場合、ユーザーが /watch の実行前に明示的に「取り込まないで」と言っていない限り、スキップしないでください)。

質問:「これを Obsidian vault に取り込みますか?」

  • はい — 同じ観点(「」)
  • はい — 別の観点(ユーザーがメモ欄に指定)
  • raw/watched/ にステージングして後で使う
  • いいえ、削除する

回答に基づく振り分け: A. はい(同じ視点または異なる視点):

  1. スラッグを作成します。report.md のフロントマターから動画のタイトルを取得し、スラッグ化(小文字、ASCII のみ、ハイフン区切り、最大 60 文字)して、-YYYY-MM-DD を追加します。例:me-at-the-zoo-2026-05-24。
  2. $VAULT_DIR/raw/watched/<slug>/ にステージングディレクトリが存在することを確認します(ステップ 4.4 ですでに作成済みです)。
  3. レポートとヒーローフレームは、ステップ 4.4 ですでにそこへコピーされています。
  4. 「異なる視点」の場合: Ingest を実行する前に、コピーしたレポートの TL;DR、Entities、Concepts の各セクションを再編集し、ユーザーが指定した新しい視点を反映します。
  5. $VAULT_DIR/CLAUDE.md が存在する場合: Ingest オペレーションの定義を更新するために読み込みます。このファイルが正式な定義であり、このスキルで手順を重複して定義してはいけません。$VAULT_DIR/CLAUDE.md の定義どおりに、raw/watched/<slug>/report.md に対して Ingest オペレーションを実行します。
  6. $VAULT_DIR/CLAUDE.md が存在しない場合: 汎用的な ingest を実行します。レポートを読み、エンティティとコンセプトを特定し、$VAULT_DIR/log.md に 1 行のエントリーを追記します(ファイルがない場合は作成します)。レポートが raw/watched/<slug>/report.md にステージングされていること、および独自の Ingest オペレーションを設定できることをユーザーに伝えます。
  7. チャットでユーザーに報告します。変更したエンティティページ(あれば)、ステージングしたレポートのパス、書き込んだ log.md のエントリーを伝えます。

B. 後で使用するために raw/watched/ にステージングする:

  1. ステップ 4.4 ですでにファイルのコピーは完了しています。
  2. Wiki には触れないでください。log.md にも追記しないでください。
  3. チャットでユーザーに次のように伝えます。「$(basename $VAULT_DIR)/raw/watched/<slug>/ にステージングしました。準備ができたら、対象に対して Ingest オペレーションを実行してください。」

C. いいえ、破棄する: ステップ 5(クリーンアップ)に進みます。ステップ 4.4 のクリーンアップに関する注意に従い、事前ステージングを取り消すために rm -rf "$VAULT_DIR/raw/watched/<slug>" を実行します。

「異なる視点」の経路により、/watch は真にプラグアンドプレイになります。ユーザーはある理由で動画を視聴した後、視聴を終える際に、実際には別のコンセプトのほうが役立つと判断できます。その結果、作成される Wiki エントリーは、その視点に合わせて内容が再構成されます。

ステップ 5 — クリーンアップ。 スクリプトは最後に作業ディレクトリを出力します。取り込みを実行した場合(ステップ 4.5 の経路 A)、ヒーローフレームと report.md はすでに Second Brain にコピーされているため、元の作業ディレクトリを rm -rf で削除できます。ステージングした場合(経路 B)も同様に、作業ディレクトリのコピーは不要です。ユーザーが「いいえ、破棄する」を選んだ場合(経路 C)で、追加の質問をする予定がなければ、rm -rf <dir> で削除します。追加の質問がありそうな場合は、そのまま残してください。

文字起こし

スクリプトは、次のいずれかの方法でタイムスタンプ付きの文字起こしを取得します。

  1. ネイティブ字幕(無料、推奨)。 利用可能な場合、yt-dlp がソースプラットフォームから手動字幕または自動生成字幕を取得します。
  2. Whisper API によるフォールバック。 字幕を取得できなかった場合(またはソースがローカルファイルの場合)、スクリプトは音声を抽出し(ffmpeg -vn -ac 1 -ar 16000 -b:a 64k、約 0.5 MB/分)、キーが設定されている Whisper API にアップロードします。
    • Groq — whisper-large-v3。デフォルトでの優先候補です。より安価で高速です。キーは console.groq.com/keys で取得できます。
    • OpenAI — whisper-1。フォールバックです。キーは platform.openai.com/api-keys で取得できます。

両方のキーは ~/.config/watch/.env に保存します。両方が設定されている場合、スクリプトは Groq を優先します。--whisper openai を指定すると OpenAI を強制的に使用できます。--no-whisper を指定すると、フォールバックを完全にスキップします。

失敗の種類と対処方法

  • セットアップ前のチェックに失敗した → python3 "${CLAUDE_SKILL_DIR}/scripts/setup.py" を実行します(macOS では brew 経由で ffmpeg/yt-dlp を自動インストールし、.env を作成します)。API キーについては、AskUserQuestion でユーザーに確認し、~/.config/watch/.env に書き込みます。
  • トランスクリプトを利用できない → 字幕がなく、かつ(Whisper キーがない、または Whisper API が失敗した)状態です。スクリプトはセットアップを案内するヒントを表示します。フレームのみで処理を進め、その旨をユーザーに伝えます。
  • 長い動画に関する警告が表示された → 回答でその旨を伝えます。動画全体をまばらにスキャンするのではなく、--start/--end を使って特定のセクションに絞り、再実行することを提案します。
  • ダウンロードに失敗した → yt-dlp のエラーは stderr に出力されます。ログインが必要な動画、または地域制限のある動画であれば、その旨をユーザーにはっきり伝えます。何度も再試行しないでください。
  • Whisper リクエストに失敗した → エラーは stderr に出力されます(主な原因:キーが無効、レート制限、または非常に長い動画での 25 MB のアップロード上限)。レポートのトランスクリプト欄には「利用可能なものはありません」と表示されます。Groq が失敗した場合は --whisper openai で再試行できます(その逆も同様です)。
  • レポートに未入力の `` マーカーがある → ステップ 4 を省略しています。戻ってレポートを読み、Edit ですべてのマーカーに入力してから、取り込みを提案してください。入力が不完全なレポートは決して取り込まないでください。Second Brain Ingest op により、内容がまばらまたは誤ったエンティティページが生成されます。
  • 取り込みが途中で失敗した → ロールバックしないでください。Second Brain Ingest op は再実行しても冪等です(ページを重複させず、既存のページを更新します)。失敗した内容をユーザーに伝え、ステージング済みの成果物を raw/watched/<slug>/ に残します。ユーザーは「<slug> のステージング済みレポートを取り込んで」と指示して再実行できます。

トークン効率

このスキルで主にトークンを消費するのはフレームです。おおよその目安:

  • 幅 512px のフレーム 80 枚で、アスペクト比によりますが、画像トークンは約 50~80k です。
  • トランスクリプトのコストは低く、10 分の動画でも最大で数千トークン程度です。
  • --resolution を 1024 に上げると、フレームあたりの画像トークンはおよそ 4 倍になります。必要な場合に限って変更してください。

このセッションですでに動画を視聴していて、ユーザーから追加の質問があった場合は、スクリプトを再実行しないでください。フレームとトランスクリプトはすでにコンテキストにあります。手元の情報に基づいて回答してください。

セキュリティと権限

このスキルが行うこと:

  • yt-dlp をローカルで実行し、動画をダウンロードして、ソースが対応している場合はネイティブ字幕を取得します(公開データです。リクエストは URL が指すホストに直接送信されます)
  • ffmpeg / ffprobe をローカルで実行し、フレームを JPEG として抽出します。また、Whisper が必要な場合はモノラル 16 kHz の音声クリップを作成します
  • GROQ_API_KEY が設定されている場合、抽出した音声クリップを Groq の Whisper API(api.groq.com/openai/v1/audio/transcriptions)に送信します(優先 — 低コストで高速です)
  • OPENAI_API_KEY が設定されていて Groq が設定されていない場合、または --whisper openai が指定された場合、抽出した音声クリップを OpenAI の音声文字起こし API(api.openai.com/v1/audio/transcriptions)に送信します
  • ダウンロードした動画、フレーム、音声、中間文字起こしデータを、Claude が Read できるようにシステムの一時ディレクトリ内(または --out-dir が指定されている場合はその場所)にある作業ディレクトリに書き込みます
  • Whisper API キーと SETUP_COMPLETE マーカーを保存するため、~/.config/watch/.env を読み取り、作成します(モード 0600)。フォールバックとして、現在の作業ディレクトリにある .env も読み取ります
  • オーケストレーション時に(取り込みが要求され、ファイルが存在する場合のみ)$VAULT_DIR/CLAUDE.md を読み取り、Vault の Ingest オペレーション定義に従います
  • Step 4.4 で Vault が検出された場合、構造化された report.md とヒーローフレームのコピーを $VAULT_DIR/raw/watched/<slug>/ に書き込みます
  • 取り込みに同意した場合、Vault の Ingest オペレーションで定義されたアクション(CLAUDE.md が存在しない場合は汎用の代替処理)に従って、$VAULT_DIR/wiki/ 配下のページ(エンティティ、概念、ソース、index.md)を読み書きし、$VAULT_DIR/log.md に追記します

このスキルが行わないこと:

  • 動画自体を API にアップロードしません — 外部に送信されるのは抽出した音声のみで、ネイティブ字幕がなく、かつ --no-whisper で Whisper が無効化されていない場合に限られます
  • プラットフォームのアカウントにアクセスしません(ログイン、セッション Cookie、投稿は行いません)
  • プロバイダー間で API キーを共有しません(Groq のキーは api.groq.com にのみ、OpenAI のキーは api.openai.com にのみ送信されます)
  • API キーをログに記録したり、キャッシュしたり、stdout、stderr、出力ファイルに書き込んだりしません
  • 作業ディレクトリと ~/.config/watch/.env の外には何も永続化しません(取り込みに同意した場合の Second Brain を除く)— 作業が終わったら作業ディレクトリをクリーンアップしてください(Step 5)
  • Step 4.5 のプロンプトでユーザーが明示的に同意することなく、Second Brain に書き込みません
  • wiki の記述を黙って上書きしません — 矛盾は Ingest オペレーションの契約に従って WARN フラグとして表面化します

同梱スクリプト: scripts/watch.py(エントリーポイント)、scripts/download.py(yt-dlp ラッパー)、scripts/frames.py(ffmpeg による均等間隔・シーン変化の抽出とヒーローフレームの選定)、scripts/pacing.py(編集指標)、scripts/hook.py(0〜10 秒の顕微鏡分析)、scripts/report.py(構造化レポートの出力)、scripts/transcribe.py(字幕の選択と Whisper のオーケストレーション)、scripts/whisper.py(Groq / OpenAI クライアント。単語レベルのタイムスタンプに対応)、scripts/setup.py(事前チェックとインストーラー)

初回使用前にスクリプトを確認し、動作を検証してください。

コメント