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 preuves lisibles
Ingestion vidéo + streaming
- Ingérer un fichier ou une URL et retourner un lien de streaming web lisible
- Transcoder/normaliser : codec, débit binaire, fps, résolution, format d'image
Indexation + recherche (horodatages + preuves)
- Construire des index visuels, vocaux et par mots-clés
- Rechercher et retourner des moments exacts avec horodatages et preuves lisibles
- Créer automatiquement des extraits à partir des résultats de recherche
Édition de timeline + génération
- Sous-titres : générer, traduire, incruster
- Overlays : texte/image/marque, légendes animées
- 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 workflows 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 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 preuves
- Ressources générées : 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 de 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 à partir de :
- L'environnement (si déjà exportée)
- Le fichier
.envdu projet dans le répertoire courant
Si la clé est manquante, videodb.connect() lève automatiquement AuthenticationError.
N'écrivez PAS de fichier de script lorsqu'une courte commande en ligne suffit.
Lors de l'écriture de code Python en ligne (python -c "..."), utilisez toujours un 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 sous 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 démarrer 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, sans carte bancaire).
Ne lisez, n'écrivez, ni ne gérez 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="/chemin/vers/video.mp4")
Transcription et sous-titres
# force=True ignore l'erreur si la vidéo est déjà indexée
video.index_spoken_words(force=True)
texte = video.get_transcript_text()
url_stream = video.add_subtitle()
Recherche dans les vidéos
from videodb.exceptions import InvalidRequestError
video.index_spoken_words(force=True)
# search() lève InvalidRequestError quand aucun résultat n'est trouvé.
# Toujours encapsuler dans un try/except et traiter "Aucun résultat trouvé" comme vide.
try:
resultats = video.search("démo produit")
plans = resultats.get_shots()
url_stream = resultats.compile()
except InvalidRequestError as e:
if "No results found" in str(e):
plans = []
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 — il lève une erreur si un index
# de scène existe déjà. Extrayez l'ID d'index existant depuis 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:
correspondance = re.search(r"id\s+([a-f0-9]+)", str(e))
if correspondance:
scene_index_id = correspondance.group(1)
else:
raise
# Utilisez score_threshold pour filtrer le bruit de faible pertinence (recommandé : 0.3+)
try:
resultats = 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,
)
plans = resultats.get_shots()
url_stream = resultats.compile()
except InvalidRequestError as e:
if "No results found" in str(e):
plans = []
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 une sortie cassée)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="La Fin", duration=3, style=TextStyle(fontsize=36)))
url_stream = timeline.generate_stream()
Transcodage vidéo (changement de résolution/qualité)
from videodb import TranscodeMode, VideoConfig, AudioConfig
# Changer la résolution, la qualité ou le format d'image 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 format d'image (pour les réseaux sociaux)
Attention : reframe() est une opération serveur lente. Pour les longues vidéos, cela peut prendre plusieurs minutes et éventuellement expirer. Bonnes pratiques :
- Limitez toujours à un court segment avec
start/endlorsque c'est possible - Pour les vidéos complètes, utilisez
callback_urlpour un traitement asynchrone - Découpez 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 :
recadre = video.reframe(start=0, end=60, cible="vertical", mode=ReframeMode.smart)
# Recadrage asynchrone pour les vidéos complètes (retourne None, résultat via webhook) :
video.reframe(cible="vertical", callback_url="https://example.com/webhook")
# Préréglages : "vertical" (9:16), "square" (1:1), "landscape" (16:9)
recadre = video.reframe(start=0, end=60, cible="square")
# Dimensions personnalisées
recadre = video.reframe(start=0, end=60, cible={"largeur": 1280, "hauteur": 720})
Génération de médias
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 |
|---|---|---|
| Indexation d'une vidéo déjà indexée | Spoken word index for video already exists | Utilisez video.index_spoken_words(force=True) pour ignorer si déjà indexé |
| Index de scène déjà existant | Scene index with id XXXX already exists | 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: No results found | Attrapez l'exception et traitez comme des résultats vides (plans = []) |
| Le recadrage expire | Bloqué indéfiniment sur les longues vidéos | Utilisez start/end pour limiter le segment, ou passez callback_url pour asynchrone |
| 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 | Operation not allowed ou maximum limit | Fonctionnalités limitées par le plan — informez l'utilisateur des limites du plan |
Exemples
Invites canoniques
- "Démarre la capture de bureau et alerte quand un champ de mot de passe apparaît."
- "Enregistre ma session et produis un résumé actionnable à la fin."
- "Ingère ce fichier et retourne un lien de streaming lisible."
- "Indexe ce dossier et trouve toutes les scènes avec des personnes, retourne les horodatages."
- "Génère des sous-titres, incruste-les et ajoute une musique de fond légère."
- "Connecte cette URL RTSP et alerte quand une personne entre dans la zone."
Enregistrement é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
- Choisissez le répertoire d'état :
STATE_DIR="${VIDEODB_EVENTS_DIR:-$HOME/.local/state/videodb}" - Démarrez le listener :
VIDEODB_EVENTS_DIR="$STATE_DIR" python scripts/ws_listener.py --clear "$STATE_DIR" & - Obtenez l'ID WebSocket :
cat "$STATE_DIR/videodb_ws_id" - Exécutez le code de capture (voir reference/capture.md pour le workflow complet)
- Événements écrits dans :
$STATE_DIR/videodb_events.jsonl
Utilisez --clear à chaque début d'une nouvelle session de capture pour éviter que des événements de transcription et visuels obsolètes ne s'infiltrent 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"
evenements = []
if events_file.exists():
with events_file.open(encoding="utf-8") as handle:
for ligne in handle:
try:
evenements.append(json.loads(ligne))
except json.JSONDecodeError:
continue
transcriptions = [e["data"]["text"] for e in evenements if e.get("channel") == "transcript"]
seuil = time.time() - 300
visuel_recent = [
e for e in evenements
if e.get("channel") == "visual_index" and e["unix_ts"] > seuil
]
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 du SDK Python VideoDB
- reference/search.md - Guide approfondi de la recherche vidéo (parole et scène)
- reference/editor.md - Édition de timeline, ressources et composition
- reference/streaming.md - Streaming HLS et lecture instantanée
- reference/generative.md - Génération de médias par IA (images, vidéo, audio)
- reference/rtstream.md - Workflow d'ingestion de flux en direct (RTSP/RTMP)
- reference/rtstream-reference.md - Méthodes du SDK RTStream et pipelines IA
- reference/capture.md - Workflow de capture de bureau
- reference/capture-reference.md - SDK de capture et événements WebSocket
- reference/use-cases.md - Modèles et exemples courants de traitement vidéo
N'utilisez pas ffmpeg, moviepy ou d'outils d'encodage locaux lorsque VideoDB prend en charge l'opération. Les opérations suivantes sont toutes gérées côté serveur par VideoDB — découpage, combinaison d'extraits, superposition audio ou musicale, ajout de sous-titres, superpositions de texte/image, transcodage, changement de résolution, conversion de format, redimensionnement pour les exigences des plateformes, 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 format d'image 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(cible="vertical") ou cible="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/découper 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 stocké localement sous skills/videodb/reference/.
Utilisez les copies locales ci-dessus plutôt que de suivre des liens de dépôts externes à l'exécution.