Compétence VideoDB
Perception + mémoire + actions pour la vidéo, les flux en direct et les sessions de bureau.
Quand l'utiliser
Perception de bureau
- Démarrer/arrêter une session de bureau capturant l'écran, le micro et l'audio système
- Diffuser un contexte en direct et stocker une mémoire de session épisodique
- Exécuter des alertes/déclencheurs en temps réel sur ce qui est dit et ce qui se passe à l'écran
- Produire des résumés de session, une timeline consultable et des liens de preuve jouables
Ingestion vidéo + streaming
- Ingérer un fichier ou une URL et retourner un lien de streaming web jouable
- Transcodage/normalisation : codec, débit, fps, résolution, rapport hauteur/largeur
Indexation + recherche (horodatages + preuves)
- Construire des index visuels, vocaux et par mots-clés
- Rechercher et retourner des moments exacts avec des horodatages et des preuves jouables
- Créer automatiquement des extraits à partir des résultats de recherche
Édition de timeline + génération
- Sous-titres : générer, traduire, incruster
- Superpositions : texte/image/marque, sous-titres animés
- Audio : musique de fond, voix-off, doublage
- Composition programmatique et exportations via opérations de timeline
Flux en direct (RTSP) + surveillance
- Connecter des flux RTSP/en direct
- Exécuter une compréhension visuelle et vocale en temps réel et émettre des événements/alertes pour les flux de travail de surveillance
Comment ça fonctionne
Entrées courantes
- Chemin de fichier local, URL publique, ou URL RTSP
- Demande de capture de bureau : démarrer / arrêter / résumer la session
- Opérations souhaitées : obtenir le contexte pour la compréhension, spécification de transcodage, spécification d'indexation, requête de recherche, plages d'extraits, modifications de timeline, règles d'alerte
Sorties courantes
- URL de streaming
- Résultats de recherche avec horodatages et liens de preuve
- Actifs générés : sous-titres, audio, images, extraits
- Données d'événement/alerte pour les flux en direct
- Résumés de session de bureau et entrées mémoire
Exécution de code Python
Avant d'exécuter du code VideoDB, placez-vous dans le répertoire du projet et chargez les variables d'environnement :
from dotenv import load_dotenv
load_dotenv(".env")
import videodb
conn = videodb.connect()
Ceci lit VIDEO_DB_API_KEY depuis :
- L'environnement (si déjà exporté)
- Le fichier
.envdu projet dans le répertoire courant
Si la clé est manquante, videodb.connect() lève automatiquement une AuthenticationError.
N'écrivez PAS de fichier de script lorsqu'une commande courte en ligne suffit.
Lorsque vous écrivez du Python en ligne (python -c "..."), utilisez toujours du code correctement formaté — utilisez des points-virgules pour séparer les instructions et gardez-le lisible. Pour tout ce qui dépasse ~3 instructions, utilisez plutôt un 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
Configuration
Lorsque l'utilisateur demande "configurer videodb" ou similaire :
1. Installer le SDK
pip install "videodb[capture]" python-dotenv
Si videodb[capture] échoue sur Linux, installez sans l'extension capture :
pip install videodb python-dotenv
2. Configurer la clé API
L'utilisateur doit définir VIDEO_DB_API_KEY en utilisant l'une ou l'autre méthode :
- Exporter dans le terminal (avant de lancer Claude) :
export VIDEO_DB_API_KEY=votre-clé - Fichier
.envdu projet : EnregistrezVIDEO_DB_API_KEY=votre-clédans le fichier.envdu projet
Obtenez une clé API gratuite sur console.videodb.io (50 téléchargements gratuits, aucune carte de crédit).
Ne lisez, n'écrivez et ne gérez PAS la clé API vous-même. Laissez toujours l'utilisateur la définir.
Référence rapide
Télécharger un média
# URL
video = coll.upload(url="https://example.com/video.mp4")
# YouTube
video = coll.upload(url="https://www.youtube.com/watch?v=VIDEO_ID")
# Fichier local
video = coll.upload(file_path="/path/to/video.mp4")
Transcription + sous-titres
# force=True ignore l'erreur si la vidéo est déjà indexée
video.index_spoken_words(force=True)
text = video.get_transcript_text()
stream_url = video.add_subtitle()
Rechercher dans les vidéos
from videodb.exceptions import InvalidRequestError
video.index_spoken_words(force=True)
# search() lève InvalidRequestError lorsqu'aucun résultat n'est trouvé.
# Toujours encapsuler dans try/except et traiter "Aucun résultat" comme vide.
try:
results = video.search("demo produit")
shots = results.get_shots()
stream_url = results.compile()
except InvalidRequestError as e:
if "Aucun résultat trouvé" in str(e):
shots = []
else:
raise
Recherche de scènes
import re
from videodb import SearchType, IndexType, SceneExtractionType
from videodb.exceptions import InvalidRequestError
# index_scenes() n'a pas de paramètre force — elle lève une erreur si un index
# de scène existe déjà. Extrayez l'ID d'index existant de l'erreur.
try:
scene_index_id = video.index_scenes(
extraction_type=SceneExtractionType.shot_based,
prompt="Décrivez le contenu visuel de cette scène.",
)
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
# Utilisez score_threshold pour filtrer le bruit de faible pertinence (recommandé : 0.3+)
try:
results = video.search(
query="personne écrivant sur un tableau blanc",
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 "Aucun résultat trouvé" in str(e):
shots = []
else:
raise
Édition de timeline
Important : Validez toujours les horodatages avant de construire une timeline :
startdoit être >= 0 (les valeurs négatives sont acceptées silencieusement mais produisent un résultat cassé)startdoit être <endenddoit être <=video.length
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="Fin", duration=3, style=TextStyle(fontsize=36)))
stream_url = timeline.generate_stream()
Transcodage vidéo (changement de résolution / qualité)
from videodb import TranscodeMode, VideoConfig, AudioConfig
# Changez la résolution, la qualité ou le rapport hauteur/largeur côté serveur
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),
)
Recadrage du rapport hauteur/largeur (pour les plateformes sociales)
Attention : reframe() est une opération serveur lente. Pour les longues vidéos, cela peut prendre plusieurs minutes et peut expirer. Bonnes pratiques :
- Limitez toujours à un court segment en utilisant
start/endlorsque possible - Pour les vidéos complètes, utilisez
callback_urlpour un traitement asynchrone - Rognez d'abord la vidéo sur une
Timeline, puis recadrez le résultat plus court
from videodb import ReframeMode
# Préférez toujours recadrer un court segment :
reframed = video.reframe(start=0, end=60, target="vertical", mode=ReframeMode.smart)
# Recadrage asynchrone pour les vidéos complètes (retourne None, résultat via webhook) :
video.reframe(target="vertical", callback_url="https://example.com/webhook")
# Préréglages : "vertical" (9:16), "square" (1:1), "landscape" (16:9)
reframed = video.reframe(start=0, end=60, target="square")
# Dimensions personnalisées
reframed = video.reframe(start=0, end=60, target={"width": 1280, "height": 720})
Médias génératifs
image = coll.generate_image(
prompt="un coucher de soleil sur les montagnes",
aspect_ratio="16:9",
)
Gestion des erreurs
from videodb.exceptions import AuthenticationError, InvalidRequestError
try:
conn = videodb.connect()
except AuthenticationError:
print("Vérifiez votre VIDEO_DB_API_KEY")
try:
video = coll.upload(url="https://example.com/video.mp4")
except InvalidRequestError as e:
print(f"Échec du téléchargement : {e}")
Pièges courants
| Scénario | Message d'erreur | Solution |
|---|---|---|
| Indexer une vidéo déjà indexée | L'index de mots parlés pour la vidéo existe déjà | Utilisez video.index_spoken_words(force=True) pour ignorer si déjà indexé |
| L'index de scène existe déjà | L'index de scène avec l'id XXXX existe déjà | Extrayez l'scene_index_id existant de l'erreur avec re.search(r"id\s+([a-f0-9]+)", str(e)) |
| La recherche ne trouve aucune correspondance | InvalidRequestError: Aucun résultat trouvé | Attrapez l'exception et traitez comme résultats vides (shots = []) |
| Le recadrage expire | Bloque indéfiniment sur les longues vidéos | Utilisez start/end pour limiter le segment, ou passez callback_url pour l'async |
| Horodatages négatifs sur la Timeline | Produit silencieusement un flux cassé | Validez toujours start >= 0 avant de créer VideoAsset |
generate_video() / create_collection() échoue | Opération non autorisée ou limite maximale | Fonctionnalités liées au plan — informez l'utilisateur des limites du plan |
Exemples
Invites canoniques
- "Démarrer la capture de bureau et alerter lorsqu'un champ de mot de passe apparaît."
- "Enregistrer ma session et produire un résumé exploitable lorsqu'elle se termine."
- "Ingérer ce fichier et retourner un lien de streaming jouable."
- "Indexer ce dossier et trouver chaque scène avec des personnes, retourner les horodatages."
- "Générer des sous-titres, les incruster, et ajouter une musique de fond légère."
- "Connecter cette URL RTSP et alerter lorsqu'une personne entre dans la zone."
Enregistrement d'écran (Capture de bureau)
Utilisez ws_listener.py pour capturer les événements WebSocket pendant les sessions d'enregistrement. La capture de bureau est prise en charge uniquement sur macOS.
Démarrage rapide
- Choisir le répertoire d'état :
STATE_DIR="${VIDEODB_EVENTS_DIR:-$HOME/.local/state/videodb}" - Démarrer l'écouteur :
VIDEODB_EVENTS_DIR="$STATE_DIR" python scripts/ws_listener.py --clear "$STATE_DIR" & - Obtenir l'ID WebSocket :
cat "$STATE_DIR/videodb_ws_id" - Exécuter le code de capture (voir reference/capture.md pour le flux de travail complet)
- Événements écrits dans :
$STATE_DIR/videodb_events.jsonl
Utilisez --clear chaque fois que vous démarrez une nouvelle capture pour que les événements de transcription et visuels obsolètes ne s'infiltrent pas dans la nouvelle session.
Interroger les événements
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
]
Documentation supplémentaire
La documentation de référence se trouve dans le répertoire reference/ adjacent à ce fichier SKILL.md. Utilisez l'outil Glob pour le localiser si nécessaire.
- reference/api-reference.md - Référence complète de l'API SDK Python VideoDB
- reference/search.md - Guide approfondi de la recherche vidéo (mots parlés et basée sur les scènes)
- reference/editor.md - Édition de timeline, actifs et composition
- reference/streaming.md - Streaming HLS et lecture instantanée
- reference/generative.md - Génération de médias alimentée par IA (images, vidéo, audio)
- reference/rtstream.md - Flux de travail d'ingestion de flux en direct (RTSP/RTMP)
- reference/rtstream-reference.md - Méthodes SDK RTStream et pipelines IA
- reference/capture.md - Flux de travail de capture de bureau
- reference/capture-reference.md - SDK de capture et événements WebSocket
- reference/use-cases.md - Modèles courants de traitement vidéo et exemples
N'utilisez pas ffmpeg, moviepy ou d'outils d'encodage local lorsque VideoDB prend en charge l'opération. Les éléments suivants sont tous gérés côté serveur par VideoDB — rognage, combinaison d'extraits, superposition audio ou musicale, ajout de sous-titres, superpositions de texte/image, transcodage, changements de résolution, conversion de rapport hauteur/largeur, redimensionnement pour les exigences de plateforme, transcription et génération de médias. Revenez aux outils locaux uniquement pour les opérations listées dans Limitations dans reference/editor.md (transitions, changements de vitesse, recadrage/zoom, étalonnage des couleurs, mixage du volume).
Quand utiliser quoi
| Problème | Solution VideoDB |
|---|---|
| La plateforme rejette le rapport hauteur/largeur ou la résolution de la vidéo | video.reframe() ou conn.transcode() avec VideoConfig |
| Besoin de redimensionner une vidéo pour Twitter/Instagram/TikTok | video.reframe(target="vertical") ou target="square" |
| Besoin de changer la résolution (ex. 1080p → 720p) | conn.transcode() avec VideoConfig(resolution=720) |
| Besoin de superposer de l'audio/de la musique sur une vidéo | AudioAsset sur une Timeline |
| Besoin d'ajouter des sous-titres | video.add_subtitle() ou CaptionAsset |
| Besoin de combiner/rogner des extraits | VideoAsset sur une Timeline |
| Besoin de générer une voix-off, de la musique ou des effets sonores | coll.generate_voice(), generate_music(), generate_sound_effect() |
Provenance
Le matériel de référence pour cette compétence est fourni localement sous skills/videodb/reference/.
Utilisez les copies locales ci-dessus au lieu de suivre les liens vers des dépôts externes lors de l'exécution.