Communitygithub.com

videodb

Voir, comprendre et agir sur la vidéo et l’audio. Ingérez, indexez, recherchez, éditez, transcodez et créez des alertes en temps réel.

Qu'est-ce que videodb ?

La compétence VideoDB offre une perception, une mémoire et des actions complètes pour la vidéo, les flux en direct et les sessions de bureau. Elle prend en charge l'ingestion à partir de fichiers locaux, d'URL, de flux RTSP ou de capture de bureau, et retourne des liens de streaming lisibles ainsi qu'un contexte en temps réel. Pour la compréhension, elle indexe le contenu visuel, sémantique et temporel, permettant une recherche précise par instants avec horodatages et extraits automatiques. Les actions incluent le transcodage (codec, fps, résolution, format), l'édition de timeline (sous-titres, overlays texte/image, doublage, traduction), la génération de médias (image, audio, vidéo) et la création d'alertes en temps réel pour les flux en direct ou la capture écran. C'est un outil puissant pour les workflows de surveillance, d'édition vidéo programmatique et d'analyse multimédia, avec un SDK Python bien documenté et une gestion d'erreurs intégrée.

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/ECC/tree/main/skills/videodb

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

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 :

  1. L'environnement (si déjà exportée)
  2. Le fichier .env du 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 .env du projet : enregistrez VIDEO_DB_API_KEY=votre-clé dans le fichier .env du 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 :

  • start doit être >= 0 (les valeurs négatives sont acceptées silencieusement mais produisent une sortie cassée)
  • start doit être < end
  • end doit ê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/end lorsque c'est possible
  • Pour les vidéos complètes, utilisez callback_url pour 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énarioMessage d'erreurSolution
Indexation d'une vidéo déjà indexéeSpoken word index for video already existsUtilisez video.index_spoken_words(force=True) pour ignorer si déjà indexé
Index de scène déjà existantScene index with id XXXX already existsExtrayez l'scene_index_id existant de l'erreur avec re.search(r"id\s+([a-f0-9]+)", str(e))
La recherche ne trouve aucune correspondanceInvalidRequestError: No results foundAttrapez l'exception et traitez comme des résultats vides (plans = [])
Le recadrage expireBloqué indéfiniment sur les longues vidéosUtilisez start/end pour limiter le segment, ou passez callback_url pour asynchrone
Horodatages négatifs sur la TimelineProduit silencieusement un flux casséValidez toujours start >= 0 avant de créer VideoAsset
generate_video(), create_collection() échoueOperation not allowed ou maximum limitFonctionnalité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

  1. Choisissez le répertoire d'état : STATE_DIR="${VIDEODB_EVENTS_DIR:-$HOME/.local/state/videodb}"
  2. Démarrez le listener : VIDEODB_EVENTS_DIR="$STATE_DIR" python scripts/ws_listener.py --clear "$STATE_DIR" &
  3. Obtenez l'ID WebSocket : cat "$STATE_DIR/videodb_ws_id"
  4. Exécutez le code de capture (voir reference/capture.md pour le workflow complet)
  5. É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.

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èmeSolution VideoDB
La plateforme rejette le format d'image ou la résolution de la vidéovideo.reframe() ou conn.transcode() avec VideoConfig
Besoin de redimensionner une vidéo pour Twitter/Instagram/TikTokvideo.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éoAudioAsset sur une Timeline
Besoin d'ajouter des sous-titresvideo.add_subtitle() ou CaptionAsset
Besoin de combiner/découper des extraitsVideoAsset sur une Timeline
Besoin de générer une voix off, de la musique ou des effets sonorescoll.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.

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/content-engine

Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.

affaan-m/ECC

Multi-platform content distribution across X, LinkedIn, Threads, and Bluesky. Adapts content per platform using content-engine patterns. Never posts identical content cross-platform. Use when the user wants to distribute content across social platforms.

affaan-m/fal-ai-media

Unified media generation via fal.ai MCP — image, video, and audio. Covers text-to-image (Nano Banana), text/image-to-video (Seedance, Kling, Veo 3), text-to-speech (CSM-1B), and video-to-audio (ThinkSound). Use when the user wants to generate images, videos, or audio with AI.

affaan-m/manim-video

日本語翻訳:このファイルは manim-video 用の日本語翻訳が必要です

affaan-m/remotion-video-creation

Remotion のベストプラクティス - React で動画を作成する。3D、アニメーション、音声、字幕、チャート、トランジションなどをカバーするドメイン固有の29のルール。

affaan-m/video-editing

AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

agent-self-evaluation

Use after completing any non-trivial task. The agent self-rates its output on 5 axes — accuracy, completeness, clarity, actionability, conciseness — with concrete evidence per criterion. Produces a structured 1-5 scorecard with specific improvement suggestions.

agent-sort

Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.

ai-first-engineering

Engineering operating model for teams where AI agents generate a large share of implementation output. Use when setting team process, review gates, or ownership rules for a codebase largely written by agents.

ai-regression-testing

Regression testing strategies for AI-assisted development. Sandbox-mode API testing without database dependencies, automated bug-check workflows, and patterns to catch AI blind spots where the same model writes and reviews code. Use when adding regression coverage to AI-assisted code, or when the same model both wrote and reviewed a change.

android-clean-architecture

Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns. Use when structuring modules, layers, or data flow in an Android or KMP project.

angular-developer

Generates Angular code and provides architectural guidance. Trigger when creating projects, components, or services, or for best practices on reactivity (signals, linkedSignal, resource), forms, dependency injection, routing, SSR, accessibility (ARIA), animations, styling (component styles, Tailwind CSS), testing, or CLI tooling.

Skills associés