VideoDB Skill
Wahrnehmung + Gedächtnis + Aktionen für Videos, Live-Streams und Desktop-Sitzungen.
Wann verwenden
Desktop-Wahrnehmung
- Desktop-Sitzung starten/stoppen, die Bildschirm, Mikrofon und Systemaudio erfasst
- Live-Kontext streamen und episodisches Sitzungsgedächtnis speichern
- Echtzeit-Benachrichtigungen/Trigger für Gesprochenes und auf dem Bildschirm Sichtbares ausführen
- Sitzungszusammenfassungen, eine durchsuchbare Zeitleiste und abspielbare Beweislinks erstellen
Video-Import + Stream
- Datei oder URL importieren und einen abspielbaren Web-Stream-Link zurückgeben
- Transkodieren/normalisieren: Codec, Bitrate, fps, Auflösung, Seitenverhältnis
Index + Suche (Zeitstempel + Beweise)
- Visuelle, gesprochene und **Schlüsselwort-**Indizes erstellen
- Nach genauen Momenten mit Zeitstempeln und abspielbaren Beweisen suchen
- Automatisch Clips aus Suchergebnissen erstellen
Zeitleisten-Bearbeitung + Generierung
- Untertitel: generieren, übersetzen, einbrennen
- Overlays: Text/Bild/Branding, Bewegungsuntertitel
- Audio: Hintergrundmusik, Voiceover, Synchronisation
- Programmatische Komposition und Exporte via Zeitleisten-Operationen
Live-Streams (RTSP) + Überwachung
- RTSP/Live-Feeds verbinden
- Echtzeit-visuelle und gesprochene Analyse durchführen und Ereignisse/Benachrichtigungen für Überwachungs-Workflows ausgeben
So funktioniert es
Häufige Eingaben
- Lokaler Dateipfad, öffentliche URL oder RTSP-URL
- Desktop-Aufnahme-Anfrage: Sitzung starten / stoppen / zusammenfassen
- Gewünschte Operationen: Kontext für Verständnis abrufen, Transkodierungsspezifikation, Indexspezifikation, Suchanfrage, Clip-Bereiche, Zeitleistenbearbeitungen, Alarmregeln
Häufige Ausgaben
- Stream-URL
- Suchergebnisse mit Zeitstempeln und Beweislinks
- Generierte Assets: Untertitel, Audio, Bilder, Clips
- Ereignis-/Alarm-Payloads für Live-Streams
- Desktop-Sitzungszusammenfassungen und Gedächtniseinträge
Python-Code ausführen
Bevor Sie VideoDB-Code ausführen, wechseln Sie in das Projektverzeichnis und laden Sie die Umgebungsvariablen:
from dotenv import load_dotenv
load_dotenv(".env")
import videodb
conn = videodb.connect()
Dies liest VIDEO_DB_API_KEY aus:
- Umgebung (falls bereits exportiert)
.env-Datei des Projekts im aktuellen Verzeichnis
Wenn der Schlüssel fehlt, löst videodb.connect() automatisch einen AuthenticationError aus.
Schreiben Sie KEINE Skriptdatei, wenn ein kurzer Inline-Befehl ausreicht.
Wenn Sie Inline-Python (python -c "...") verwenden, formatieren Sie den Code immer korrekt – verwenden Sie Semikolons, um Anweisungen zu trennen, und halten Sie es lesbar. Für mehr als ~3 Anweisungen verwenden Sie stattdessen einen Heredoc:
python << 'EOF'
from dotenv import load_dotenv
load_dotenv(".env")
import videodb
conn = videodb.connect()
coll = conn.get_collection()
print(f"Videos: {len(coll.get_videos())}")
EOF
Einrichtung
Wenn der Benutzer „videodb einrichten“ oder ähnlich sagt:
1. SDK installieren
pip install "videodb[capture]" python-dotenv
Falls videodb[capture] unter Linux fehlschlägt, installieren Sie ohne das Capture-Extra:
pip install videodb python-dotenv
2. API-Schlüssel konfigurieren
Der Benutzer muss VIDEO_DB_API_KEY mit einer der folgenden Methoden setzen:
- Im Terminal exportieren (vor dem Start von Gemini):
export VIDEO_DB_API_KEY=your-key - Projekt-
.env-Datei: Speichern SieVIDEO_DB_API_KEY=your-keyin der.env-Datei des Projekts
Holen Sie sich einen kostenlosen API-Schlüssel unter console.videodb.io (50 kostenlose Uploads, keine Kreditkarte erforderlich).
Lesen, schreiben oder verarbeiten Sie den API-Schlüssel NICHT selbst. Lassen Sie den Benutzer ihn immer setzen.
Kurzreferenz
Medien hochladen
# URL
video = coll.upload(url="https://example.com/video.mp4")
# YouTube
video = coll.upload(url="https://www.youtube.com/watch?v=VIDEO_ID")
# Lokale Datei
video = coll.upload(file_path="/path/to/video.mp4")
Transkript + Untertitel
# force=True überspringt den Fehler, wenn das Video bereits indiziert ist
video.index_spoken_words(force=True)
text = video.get_transcript_text()
stream_url = video.add_subtitle()
In Videos suchen
from videodb.exceptions import InvalidRequestError
video.index_spoken_words(force=True)
# search() löst InvalidRequestError aus, wenn keine Ergebnisse gefunden werden.
# Immer in try/except verpacken und „Keine Ergebnisse gefunden“ als leeres Ergebnis behandeln.
try:
results = video.search("Produktdemo")
shots = results.get_shots()
stream_url = results.compile()
except InvalidRequestError as e:
if "No results found" in str(e):
shots = []
else:
raise
Szenensuche
import re
from videodb import SearchType, IndexType, SceneExtractionType
from videodb.exceptions import InvalidRequestError
# index_scenes() hat keinen force-Parameter – es löst einen Fehler aus, wenn ein
# Szenenindex bereits existiert. Extrahieren Sie die vorhandene Index-ID aus dem Fehler.
try:
scene_index_id = video.index_scenes(
extraction_type=SceneExtractionType.shot_based,
prompt="Beschreiben Sie den visuellen Inhalt dieser Szene.",
)
except Exception as e:
match = re.search(r"id\s+([a-f0-9]+)", str(e))
if match:
scene_index_id = match.group(1)
else:
raise
# Verwenden Sie score_threshold, um Rauschen mit niedriger Relevanz herauszufiltern (empfohlen: 0,3+)
try:
results = video.search(
query="Person, die an ein Whiteboard schreibt",
search_type=SearchType.semantic,
index_type=IndexType.scene,
scene_index_id=scene_index_id,
score_threshold=0.3,
)
shots = results.get_shots()
stream_url = results.compile()
except InvalidRequestError as e:
if "No results found" in str(e):
shots = []
else:
raise
Zeitleisten-Bearbeitung
Wichtig: Überprüfen Sie Zeitstempel immer, bevor Sie eine Zeitleiste erstellen:
startmuss >= 0 sein (negative Werte werden still akzeptiert, erzeugen aber defekte Ausgaben)startmuss <endseinendmuss <=video.lengthsein
from videodb.timeline import Timeline
from videodb.asset import VideoAsset, TextAsset, TextStyle
timeline = Timeline(conn)
timeline.add_inline(VideoAsset(asset_id=video.id, start=10, end=30))
timeline.add_overlay(0, TextAsset(text="The End", duration=3, style=TextStyle(fontsize=36)))
stream_url = timeline.generate_stream()
Video transkodieren (Auflösung / Qualität ändern)
from videodb import TranscodeMode, VideoConfig, AudioConfig
# Ändern Sie Auflösung, Qualität oder Seitenverhältnis serverseitig
job_id = conn.transcode(
source="https://example.com/video.mp4",
callback_url="https://example.com/webhook",
mode=TranscodeMode.economy,
video_config=VideoConfig(resolution=720, quality=23, aspect_ratio="16:9"),
audio_config=AudioConfig(mute=False),
)
Seitenverhältnis anpassen (für soziale Plattformen)
Warnung: reframe() ist eine langsame serverseitige Operation. Bei langen Videos kann sie
mehrere Minuten dauern und ggf. ein Timeout verursachen. Best Practices:
- Beschränken Sie den Vorgang möglichst mit
start/endauf ein kurzes Segment - Verwenden Sie bei vollständigen Videos
callback_urlfür die asynchrone Verarbeitung - Schneiden Sie das Video zuerst auf einer
Timelinezurecht und passen Sie dann das kürzere Ergebnis an
from videodb import ReframeMode
# Bevorzugen Sie immer die Anpassung eines kurzen Segments:
reframed = video.reframe(start=0, end=60, target="vertical", mode=ReframeMode.smart)
# Asynchrone Anpassung für vollständige Videos (gibt None zurück, Ergebnis via Webhook):
video.reframe(target="vertical", callback_url="https://example.com/webhook")
# Voreinstellungen: "vertical" (9:16), "square" (1:1), "landscape" (16:9)
reframed = video.reframe(start=0, end=60, target="square")
# Benutzerdefinierte Abmessungen
reframed = video.reframe(start=0, end=60, target={"width": 1280, "height": 720})
Generative Medien
image = coll.generate_image(
prompt="ein Sonnenuntergang über Bergen",
aspect_ratio="16:9",
)
Fehlerbehandlung
from videodb.exceptions import AuthenticationError, InvalidRequestError
try:
conn = videodb.connect()
except AuthenticationError:
print("Überprüfen Sie Ihren VIDEO_DB_API_KEY")
try:
video = coll.upload(url="https://example.com/video.mp4")
except InvalidRequestError as e:
print(f"Upload fehlgeschlagen: {e}")
Häufige Fallstricke
| Szenario | Fehlermeldung | Lösung |
|---|---|---|
| Indizieren eines bereits indizierten Videos | Spoken word index for video already exists | video.index_spoken_words(force=True) verwenden, um bei bereits vorhandenem Index zu überspringen |
| Szenenindex existiert bereits | Scene index with id XXXX already exists | Vorhandene scene_index_id aus dem Fehler mit re.search(r"id\s+([a-f0-9]+)", str(e)) extrahieren |
| Suche findet keine Übereinstimmungen | InvalidRequestError: No results found | Ausnahme abfangen und als leere Ergebnisse behandeln (shots = []) |
| Reframe-Zeitüberschreitung | Blockiert auf unbestimmte Zeit bei langen Videos | start/end verwenden, um Segment zu begrenzen, oder callback_url für asynchrone Verarbeitung übergeben |
| Negative Zeitstempel in der Timeline | Erzeugt stillschweigend defekten Stream | Immer start >= 0 vor Erstellung von VideoAsset validieren |
generate_video() / create_collection() schlägt fehl | Operation not allowed oder maximum limit | Tarifabhängige Funktionen – Benutzer über Tarifbeschränkungen informieren |
Beispiele
Beispielhafte Eingabeaufforderungen
- „Desktop-Aufnahme starten und alarmieren, wenn ein Passwortfeld erscheint.“
- „Meine Sitzung aufzeichnen und eine verwertbare Zusammenfassung erstellen, wenn sie endet.“
- „Diese Datei importieren und einen abspielbaren Stream-Link zurückgeben.“
- „Diesen Ordner indizieren und jede Szene mit Personen finden, mit Zeitstempeln.“
- „Untertitel generieren, einbrennen und leichte Hintergrundmusik hinzufügen.“
- „Diese RTSP-URL verbinden und alarmieren, wenn eine Person die Zone betritt.“
Bildschirmaufnahme (Desktop-Aufnahme)
Verwenden Sie ws_listener.py, um WebSocket-Ereignisse während Aufnahmesitzungen zu erfassen. Desktop-Aufnahme wird nur unter macOS unterstützt.
Schnellstart
- Statusverzeichnis wählen:
STATE_DIR="${VIDEODB_EVENTS_DIR:-$HOME/.local/state/videodb}" - Listener starten:
VIDEODB_EVENTS_DIR="$STATE_DIR" python scripts/ws_listener.py --clear "$STATE_DIR" & - WebSocket-ID abrufen:
cat "$STATE_DIR/videodb_ws_id" - Aufnahmecode ausführen (siehe reference/capture.md für den vollständigen Workflow)
- Ereignisse werden geschrieben nach:
$STATE_DIR/videodb_events.jsonl
Verwenden Sie --clear, wann immer Sie eine neue Aufnahme starten, damit alte Transkript- und visuelle Ereignisse nicht in die neue Sitzung eindringen.
Ereignisse abfragen
import json
import os
import time
from pathlib import Path
events_dir = Path(os.environ.get("VIDEODB_EVENTS_DIR", Path.home() / ".local" / "state" / "videodb"))
events_file = events_dir / "videodb_events.jsonl"
events = []
if events_file.exists():
with events_file.open(encoding="utf-8") as handle:
for line in handle:
try:
events.append(json.loads(line))
except json.JSONDecodeError:
continue
transcripts = [e["data"]["text"] for e in events if e.get("channel") == "transcript"]
cutoff = time.time() - 300
recent_visual = [
e for e in events
if e.get("channel") == "visual_index" and e["unix_ts"] > cutoff
]
Zusätzliche Dokumentation
Die Referenzdokumentation befindet sich im Verzeichnis reference/ neben dieser SKILL.md-Datei. Verwenden Sie das Glob-Tool, um sie bei Bedarf zu finden.
- reference/api-reference.md – Vollständige VideoDB Python SDK API-Referenz
- reference/search.md – Ausführlicher Leitfaden zur Videosuche (gesprochene Wörter und szenenbasiert)
- reference/editor.md – Zeitleistenbearbeitung, Assets und Komposition
- reference/streaming.md – HLS-Streaming und sofortige Wiedergabe
- reference/generative.md – KI-gestützte Mediengenerierung (Bilder, Video, Audio)
- reference/rtstream.md – Live-Stream-Import-Workflow (RTSP/RTMP)
- reference/rtstream-reference.md – RTStream SDK-Methoden und KI-Pipelines
- reference/capture.md – Desktop-Aufnahme-Workflow
- reference/capture-reference.md – Capture SDK und WebSocket-Ereignisse
- reference/use-cases.md – Häufige Videoverarbeitungsmuster und Beispiele
Verwenden Sie kein ffmpeg, moviepy oder lokale Kodierungstools, wenn VideoDB die Operation unterstützt. Alle folgenden Operationen werden serverseitig von VideoDB durchgeführt: Trimmen, Kombinieren von Clips, Überlagern von Audio oder Musik, Hinzufügen von Untertiteln, Text-/Bild-Overlays, Transkodierung, Auflösungsänderung, Seitenverhältnis-Konvertierung, Größenänderung für Plattformanforderungen, Transkription und Medienerzeugung. Verwenden Sie lokale Tools nur für Operationen, die unter „Limitations“ in reference/editor.md aufgeführt sind (Übergänge, Geschwindigkeitsänderungen, Zuschneiden/Zoom, Farbkorrektur, Lautstärkemischung).
Wann was verwenden
| Problem | VideoDB-Lösung |
|---|---|
| Plattform lehnt Video-Seitenverhältnis oder Auflösung ab | video.reframe() oder conn.transcode() mit VideoConfig |
| Video für Twitter/Instagram/TikTok zuschneiden | video.reframe(target="vertical") oder target="square" |
| Auflösung ändern (z. B. 1080p → 720p) | conn.transcode() mit VideoConfig(resolution=720) |
| Audio/Musik über Video legen | AudioAsset auf einer Timeline |
| Untertitel hinzufügen | video.add_subtitle() oder CaptionAsset |
| Clips kombinieren/trimmen | VideoAsset auf einer Timeline |
| Voiceover, Musik oder Soundeffekte generieren | coll.generate_voice(), generate_music(), generate_sound_effect() |
Herkunft
Referenzmaterial für dieses Skill wird lokal unter skills/videodb/reference/ bereitgestellt.
Verwenden Sie die lokalen Kopien anstelle von externen Repository-Links zur Laufzeit.