/watch
Du hast keine Videoeingabe; diese Skill gibt dir eine. Ein Python-Skript holt zuerst Untertitel, lädt optional das Video herunter, extrahiert Einzelbilder als JPEGs (szenenbewusst oder schnelle Keyframes bei efficient-Detail), erhält ein zeitgestempeltes Transkript (native Untertitel zuerst, dann Whisper-API als Fallback) und gibt die Bildpfade aus. Du liest dann jeden Bildpfad mit Read, um die Bilder zu sehen, und kombinierst sie mit dem Transkript, um die Frage des Benutzers zu beantworten.
Auflösen von SKILL_DIR (vor jedem Befehl ausführen)
Jeder python3 ...-Befehl unten führt ein gebündeltes Skript unter SKILL_DIR/scripts/ aus. Setze SKILL_DIR auf den absoluten Pfad des Verzeichnisses, das DIESE SKILL.md enthält, die du gerade gelesen hast — dein Harness hat dir diesen Pfad im Leseergebnis mitgeteilt. Die Skripte befinden sich immer direkt neben dieser Datei (SKILL_DIR/scripts/watch.py), in jeder Installationsstruktur:
Read ~/.claude/plugins/cache/claude-video/watch/<ver>/skills/watch/SKILL.md → SKILL_DIR=…/skills/watch
Read ~/.codex/skills/watch/SKILL.md → SKILL_DIR=~/.codex/skills/watch
Read ~/.agents/skills/watch/SKILL.md → SKILL_DIR=~/.agents/skills/watch
Ersetze diesen wörtlichen Pfad für ${SKILL_DIR} in jedem Befehl. Dies funktioniert in jedem Harness (Claude Code, Codex, Cursor, Gemini CLI, …), ohne sich auf eine harness-spezifische Umgebungsvariable zu verlassen. Führe zu Beginn eines Durchlaufs einmal eine Prüfung durch:
SKILL_DIR="<absoluter Pfad des Verzeichnisses, das die gelesene SKILL.md enthält>"
if [ ! -f "$SKILL_DIR/scripts/watch.py" ]; then
echo "FEHLER: scripts/watch.py nicht gefunden unter SKILL_DIR=$SKILL_DIR" >&2
echo "Überprüfe das Verzeichnis der gelesenen SKILL.md und setze es als SKILL_DIR ein." >&2
exit 1
fi
Schritt 0 — Setup-Vorbereitung (wird bei jedem /watch-Aufruf ausgeführt, still bei Erfolg)
Python-Interpreter: Jeder python3 ...-Befehl in dieser Skill ist für macOS/Linux. Unter Windows ersetze mit python — der python3-Befehl unter Windows ist der Microsoft Store-Stub und führt das Skript nicht aus.
Beim ersten /watch-Aufruf in einer Sitzung verwende eine strukturierte Vorbereitung, um die Einrichtung beim ersten Start zu erkennen:
python3 "${SKILL_DIR}/scripts/setup.py" --json
Verzweige basierend auf zwei Feldern:
can_proceed: trueundfirst_run: false→ Setup ist bereits abgeschlossen (der Benutzer hat möglicherweise absichtlich einen Whisper-Schlüssel übersprungen — das ist erlaubt). Fahre mit Schritt 1 fort, ohne einen Kommentar zu hinterlassen.first_run: true→ Echte Ersteinrichtung. Führe diese Schritte in der angegebenen Reihenfolge aus:- Wenn
missing_binariesnicht leer ist, führe zuerst den Installer aus (er installiert automatisch unter macOS / gibt Befehle für andere Systeme aus — siehe unten) und bestätige, dass die Binärdateien vorhanden sind. Überspringe dies nicht und springe nicht zu den Einstellungen. - Führe den Installer bei Bedarf erneut aus, damit er
~/.config/watch/.enverstellt (er schreibt die Vorlage nur, wenn die Datei nicht vorhanden ist, lasse ihn die Datei also bevor du Werte hineinschreibst, anlegen). - Empfehle einen Whisper-API-Schlüssel und stelle die unten stehenden Fragen zu den Beobachtungseinstellungen. Schreibe dann die ausgewählten Werte in
~/.config/watch/.envund setzeSETUP_COMPLETE=true.
- Wenn
can_proceed: falseundfirst_run: false→ Setup wurde zuvor abgeschlossen, aber die Umgebung hat sich verschlechtert (z. B.missing_binariesnach einer OS-Änderung). Führe den Installer zur Behebung aus und fahre dann fort. Stelle die Einstellungen nicht erneut abfragen.
Ein fehlender Whisper-Schlüssel wird zur Behebung empfohlen, ist aber nicht erforderlich: Bei einem echten ersten Durchlauf zeigt status den Wert needs_key an, selbst wenn Binärdateien vorhanden sind — das ist dein Hinweis, einen Schlüssel zu empfehlen, kein Hindernis.
Bei nachfolgenden /watch-Aufrufen in derselben Sitzung verwende die stille Prüfung:
python3 "${SKILL_DIR}/scripts/setup.py" --check
Dies ist eine Suche unter 100 ms. Exit 0 bedeutet, dass /watch ausgeführt werden kann — dies schließt einen Benutzer ein, der das Setup ohne Whisper-Schlüssel abgeschlossen hat (schlüssellos ist erlaubt). Bei Exit 0 gibt das Skript nichts aus — fahre ohne Kommentar mit Schritt 1 fort. Verkünde dem Benutzer NICHT, dass "das Setup abgeschlossen ist" — er benötigt keine Statusmeldung bei jedem Durchlauf. Die einzig akzeptable benutzersichtbare Ausgabe von Schritt 0 ist, wenn eine Behebung erforderlich ist.
Bei Exit ungleich Null folge der Tabelle:
| Exit | Bedeutung | Aktion |
|---|---|---|
2 | Fehlende Binärdateien (ffmpeg / ffprobe / yt-dlp) | Installer ausführen |
3 | Echter erster Durchlauf ohne Whisper-API-Schlüssel | Installer ausführen, um .env zu erstellen, dann einen Schlüssel empfehlen (der Benutzer kann ablehnen — mit --no-whisper fortfahren) |
4 | Beides fehlt | Installer ausführen, dann einen Schlüssel empfehlen |
Exit 3 wird nur ausgelöst, bevor der Benutzer das Setup abgeschlossen hat. Sobald SETUP_COMPLETE=true geschrieben wurde, gibt eine schlüssellose Installation Exit 0 zurück und wird nie wieder beanstandet.
Der Installer ist idempotent — sicher wiederholbar:
python3 "${SKILL_DIR}/scripts/setup.py"
Unter macOS mit Homebrew installiert er automatisch ffmpeg und yt-dlp. Unter Linux/Windows gibt er die genauen Installationsbefehle aus, die der Benutzer ausführen muss. Er erstellt ~/.config/watch/.env mit auskommentierten Platzhaltern und Standardbeobachtungseinstellungen mit Berechtigungen 0600.
Wenn nach der Installation noch ein API-Schlüssel fehlt: Verwende AskUserQuestion, um den Benutzer zu fragen, ob er einen Groq-API-Schlüssel (bevorzugt — günstiger, schneller) oder einen OpenAI-Schlüssel hat. Schreibe ihn dann in ~/.config/watch/.env — setze die entsprechende Zeile GROQ_API_KEY=... oder OPENAI_API_KEY=.... Wenn er Whisper nicht einrichten möchte, fahre mit --no-whisper fort und teile ihm mit, dass Videos ohne native Untertitel nur als Bilder zurückkommen.
Beobachtungseinstellungen beim ersten Durchlauf: Nachdem der Installer ~/.config/watch/.env erstellt hat, verwende AskUserQuestion, um eine Frage zu stellen:
- Standard-Detail (eine Einstellung). Präsentiere diese als
AskUserQuestion-Optionen in genau dieser Reihenfolge — von leicht bis schwer — und behalte(empfohlen)beibalanced, auch wenn es nicht an erster Stelle steht (sortiere nicht um, um die empfohlene Option an die erste Stelle zu setzen):transcript— keine Einzelbilder, nur Transkript (überspringt den Video-Download, wenn Untertitel vorhanden sind).efficient— schneller Keyframe-Durchlauf (max. 50).balanced(empfohlen) — szenenbewusste Einzelbilder (max. 100, Standard).token-burner— szenenbewusst, unbegrenzt (maximale Detailtreue; hohe Token-Kosten).
Schreibe die Antwort direkt in ~/.config/watch/.env, indem du den bloßen Schlüssel in eine eigene Zeile setzt — keinen nachgestellten Inline-Kommentar (ein # Hinweis nach dem Wert kann die Analyse stören):
WATCH_DETAIL=balanced
Verwende den vom Benutzer ausgewählten Wert. Wenn er die Frage überspringt, behalte die empfohlene Standardeinstellung. Sobald Abhängigkeiten, die API-Schlüsselauswahl und diese Einstellung behandelt wurden, schreibe oder aktualisiere SETUP_COMPLETE=true in derselben Datei. Frage diese Einstellung nicht erneut ab, wenn SETUP_COMPLETE=true ist.
Strukturierter Modus (optional): python3 "${SKILL_DIR}/scripts/setup.py" --json gibt {status, can_proceed, first_run, setup_complete, missing_binaries, whisper_backend, has_api_key, config_file, watch_detail, platform} aus, wobei status einer von ready | needs_install | needs_key | needs_install_and_key ist. status beschreibt den idealen Zustand (ein Schlüssel wird empfohlen, daher liest ein schlüsselloser erster Durchlauf needs_key); can_proceed ist das operative Tor (Binärdateien vorhanden UND ein Schlüssel ist gesetzt ODER das Setup wurde bereits abgeschlossen). Verzweige basierend auf can_proceed/first_run, um zu entscheiden, ob du fortfährst; verwende status, um zu entscheiden, was empfohlen werden soll.
Innerhalb einer Sitzung kannst du Schritt 0 bei nachfolgenden /watch-Aufrufen überspringen — sobald --check 0 zurückgegeben hat, ändert sich nichts an der Umgebung zwischen den Durchläufen.
Wann verwenden
- Benutzer fügt eine Video-URL ein (YouTube, Vimeo, X, TikTok, Twitch-Clip, die meisten yt-dlp-unterstützten Seiten) und stellt eine Frage dazu.
- Benutzer zeigt auf eine lokale Videodatei (
.mp4,.mov,.mkv,.webmusw.) und stellt eine Frage dazu. - Benutzer gibt
/watch <url-oder-pfad> [frage]ein.
Empfohlene Grenzen
- Beste Genauigkeit: Videos unter 10 Minuten. Die Bildabdeckung skaliert umgekehrt proportional zur Dauer.
- Universelle Ratenbegrenzung: 2 fps. Das Skript tastet nie schneller als 2 fps ab, selbst wenn ein Budget oder
--fpsmehr bedeuten würde. - Die Bildobergrenze wird durch den Detailmodus festgelegt (
WATCH_DETAILin~/.config/watch/.envoder--detail), nicht durch eine einzelne globale Obergrenze:transcript→ keine Einzelbilderefficient→ bis zu 50 (Keyframes)balanced(Standard) → bis zu 100 (szenenbewusst)token-burner→ unbegrenzt (szenenbewusst; eine leichte Warnung wird ab 250 Einzelbildern ausgegeben)--max-frames Nüberschreibt die jeweilige Obergrenze, die der Modus sonst verwenden würde.
- Gesamtvideo-Bildbudget nach Dauer. Die Token-Kosten steigen mit der Bildanzahl, daher zielt das Skript auf ein Budget nach Dauer ab. Dieses Budget legt die fps und den gleichmäßigen Abtastungs-Fallback fest; die szenenbewusste Auswahl kann bis zur oben genannten Detailobergrenze auffüllen, je nachdem, was niedriger ist:
- ≤30s → ~12-30 Einzelbilder
- 30s-1min → ~40 Einzelbilder
- 1-3min → ~60 Einzelbilder
- 3-10min → ~80 Einzelbilder
-
10min → bis zur Detailobergrenze, weit auseinanderliegend (Warnung wird ausgegeben)
- Wenn der Benutzer dir ein langes Video gibt, frage nach, ob er einen bestimmten Abschnitt wünscht, bevor du Token für eine spärliche Abtastung verbrennst.
Wie aufrufen
Schritt 1 — Benutzereingabe analysieren. Trenne die Videoquelle (URL oder Pfad) von einer eventuellen Frage des Benutzers. Beispiel: /watch https://youtu.be/abc in welcher Sprache ist das? → quelle = https://youtu.be/abc, frage = in welcher Sprache ist das?.
Schritt 2 — Das Watch-Skript ausführen. Übergib die Quelle unverändert. Maskiere die Shell nicht selbst über normales Zitieren hinaus:
python3 "${SKILL_DIR}/scripts/watch.py" "<quelle>"
Optionale Flags:
--detail transcript|efficient|balanced|token-burner— Detail-/Geschwindigkeitsregler.transcript= keine Einzelbilder (nur Transkript, überspringt Video-Download, wenn Untertitel vorhanden sind);efficient= schnelle Keyframes (max. 50);balanced= szenenbewusste Einzelbilder (max. 100);token-burner= szenenbewusst, unbegrenzt.--start T/--end T— Fokus auf einen Abschnitt. AkzeptiertSS,MM:SSoderHH:MM:SS. Wenn einer von beiden gesetzt ist, wird die fps automatisch dichter skaliert (siehe "Fokussieren auf einen Abschnitt" unten).--timestamps T1,T2,…— ein Einzelbild zu jedem dieser absoluten Zeitstempel erfassen (SS,MM:SSoderHH:MM:SS). Verwende dies nach dem Lesen des Transkripts, um deiktische Momente einzufangen, die der Moderator hervorhebt ("schau hier", "wie du siehst", "beachte dies"), die die visuelle Auswahl allein möglicherweise übersieht. Siehe "Transkript-Hinweis-Einzelbilder" unten.--max-frames N— überschreibe die voreingestellte Obergrenze für ein engeres Token-Budget (z. B.--max-frames 40)--resolution W— ändere die Bildbreite in Pixeln (Standard 512; nur auf 1024 erhöhen, wenn der Benutzer Text auf dem Bildschirm lesen muss)--fps F— überschreibe die automatische fps (auf maximal 2 fps begrenzt)--out-dir DIR— Arbeitsdateien an einem bestimmten Ort behalten (Standard: ein automatisch generiertes tmp-Verzeichnis)--whisper groq|openai— ein bestimmtes Whisper-Backend erzwingen (Standard: bevorzuge Groq, wenn beide Schlüssel vorhanden sind)--no-thinker— den Whisper-Fallback vollständig deaktivieren (nur Einzelbilder, wenn keine Untertitel vorhanden sind)--no-dedup— nahezu identische Einzelbilder behalten. Standardmäßig verwirft ein Bilddifferenz-Durchlauf Einzelbilder, die visuell nahezu identisch mit dem vorherigen beibehaltenen sind (festgehaltene Folien, statische Bildschirmaufnahmen, pausierte Videos), damit das Bildbudget für eindeutige Inhalte verwendet wird; die Zeile Einzelbilder im Bericht gibt an, wie viele verworfen wurden. Verwende dies nur, wenn der Benutzer jedes abgetastete Einzelbild benötigt (z. B. zur Beurteilung der Bewegung von Einzelbild zu Einzelbild).
Fokussieren auf einen Abschnitt (höhere Bildrate)
Wenn der Benutzer nach einem bestimmten Moment fragt — "Was passiert bei der 2-Minuten-Marke?", "Vergrößere auf 0:45 bis 1:00", "die ersten 10 Sekunden" — übergib --start und/oder --end. Das Skript wechselt zu fokussierten Modus-Budgets, die dichter sind als die Gesamtvideo-Budgets (immer noch auf 2 fps begrenzt und immer noch durch die Detailmodus-Obergrenze begrenzt — die folgenden Zählungen gehen von der Standard-balanced-Obergrenze von 100 aus; efficient endet bei 50):
- ≤5s → 2 fps (bis zu 10 Einzelbilder)
- 5-15s → 2 fps (bis zu 30 Einzelbilder)
- 15-30s → ~2 fps (bis zu 60 Einzelbilder)
- 30-60s → ~1,3 fps (bis zu 80 Einzelbilder)
- 60-180s → ~0,6 fps (100 Einzelbilder, begrenzt)
Der fokussierte Modus ist die richtige Wahl für:
- Jeden Moment/Bereich, den der Benutzer explizit nennt ("um 2:30", "das Intro", "die letzten 30 Sekunden").
- Jedes Video, das länger als ~10 Minuten ist, wenn die Frage des Benutzers einen bestimmten Teil betrifft — das Ausführen des fokussierten Modus auf den relevanten Abschnitt ist weitaus nützlicher als eine spärliche Abtastung des gesamten Videos.
- Wiederholte Durchläufe, nachdem eine vollständige Abtastung in einem Bereich nicht genügend Details hatte.
Das Transkript wird automatisch auf denselben Bereich gefiltert. Die Bild-Zeitstempel sind absolut (echter Video-Zeitstrahl, nicht versetzt vom Start).
Beispiele:
# Letzte 10 Sekunden eines 1-minütigen Videos
python3 "${SKILL_DIR}/scripts/watch.py" video.mp4 --start 50 --end 60
# Vergrößere auf 2:15 → 2:45 bei 2 fps (60 Einzelbilder)
python3 "${SKILL_DIR}/scripts/watch.py" "$URL" --start 2:15 --end 2:45 --fps 2
# Von 1h12m bis zum Ende des Videos
python3 "${SKILL_DIR}/scripts/watch.py" "$URL" --start 1:12:00
Schritt 3 — Jeden vom Skript aufgeführten Bildpfad lesen. Das Read-Tool rendert JPEGs direkt als Bilder für dich. Lese alle Einzelbilder in einer einzigen Nachricht (parallele Tool-Aufrufe), damit du sie zusammen siehst. Die Einzelbilder sind in chronologischer Reihenfolge mit einem t=MM:SS-Zeitstempel, damit du sie mit dem Transkript abgleichen kannst.
Schritt 4 — Dem Benutzer antworten. Du hast jetzt zwei Beweisstränge:
- Einzelbilder — was auf dem Bildschirm zu jedem Zeitstempel zu sehen ist
- Transkript — was zu jedem Zeitstempel gesagt wird. Der Kopf des Berichts zeigt die Quelle an (
captions= yt-dlp hat native Untertitel gezogen;whisper (groq)oderwhisper (openai)= von der API transkribiert).
Wenn der Benutzer eine bestimmte Frage gestellt hat, beantworte sie direkt unter Angabe von Zeitstempeln. Wenn er nichts gefragt hat, fasse zusammen, was im Video passiert — Struktur, Schlüsselmomente, bemerkenswerte Bilder, gesprochener Inhalt.
Dies gilt auch für die transcript-Detailstufe: Selbst ohne Einzelbilder erstelle eine Zusammenfassung wie die anderen Modi — füge das vollständige Transkript nicht in den Chat ein. Synthetisiere Struktur, Schlüsselmomente und gesprochenen Inhalt mit Zeitstempeln; zitiere nur die relevanten Zeilen. Biete das rohe Transkript nur an, wenn der Benutzer explizit danach fragt.
Schritt 5 — Bereinigung. Das Skript gibt am Ende ein Arbeitsverzeichnis aus. Wenn der Benutzer keine weiteren Fragen zu diesem Video stellen wird, lösche es mit rm -rf <verz>. Wenn er es könnte, lasse es an Ort und Stelle.
Detail und Einzelbilder
Das Standardverhalten stammt aus ~/.config/watch/.env:
WATCH_DETAIL=transcript|efficient|balanced|token-burner(Standard:balanced)
At `
…
[gekürzt zur Übersetzung]