Communitygithub.com

DekaPrayoga/AurixAgent

Voir, comprendre et agir sur la vidéo et l'audio. Ingestion, indexation, recherche, édition et génération de médias, y compris en direct et capture de bureau.

Qu'est-ce que AurixAgent ?

Cette compétence permet à un agent IA (comme Claude Code, Cursor, ou Codex) de percevoir, comprendre et agir sur des contenus vidéo et audio. Elle offre un ensemble complet de fonctionnalités : l'ingestion à partir de fichiers locaux, d'URL, de flux RTSP ou de la capture d'écran/micro, la construction d'index visuels, sémantiques et temporels pour rechercher des moments précis avec horodatages, et l'exécution d'actions comme le transcodage, l'édition de timeline (sous-titres, superpositions, doublage), la génération de médias (image, audio, vidéo) et la création d'alertes en temps réel sur des événements. Basée sur le SDK Python `videodb`, elle gère toutes les opérations lourdes côté serveur, vous évitant d'utiliser des outils locaux comme ffmpeg. Les cas d'utilisation typiques incluent l'analyse de réunions, le montage vidéo programmatique, la surveillance de flux en direct, ou la production de contenu pour les réseaux sociaux.

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/DekaPrayoga/AurixAgent/tree/HEAD/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 AurixAgent (basée sur VideoDB)

Perception + mémoire + actions pour la vidéo, les flux en direct et les sessions de bureau.

Quand l'utiliser

Perception Bureau

  • Démarrer/arrêter une session de bureau capturant l'écran, le micro et l'audio système
  • Diffuser le contexte en direct et stocker la mémoire épisodique de la session
  • 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 chronologie consultable et des liens de preuve lisibles

Ingestion vidéo + flux

  • Ingérer un fichier ou une URL et renvoyer un lien de flux web lisible
  • Transcodifier/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 renvoyer des moments exacts avec horodatages et preuves lisibles
  • Créer automatiquement des extraits à partir des résultats de recherche

Édition de chronologie + génération

  • Sous-titres : générer, traduire, incruster
  • Superpositions : texte/image/marque, légendes animées
  • Audio : musique de fond, voix off, doublage
  • Composition programmatique et exportations via opérations de chronologie

Flux en direct (RTSP) + surveillance

  • Connecter 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 communes

  • 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écifications de transcodage, spécifications d'indexation, requête de recherche, plages d'extraits, modifications de chronologie, règles d'alerte

Sorties communes

  • URL du flux
  • Résultats de recherche avec horodatages et liens de preuve
  • Actifs générés : sous-titres, audio, images, extraits
  • Charges utiles d'événements/alertes 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 à partir de :

  1. L'environnement (si déjà exporté)
  2. Le fichier .env du 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 un code correctement formaté — utilisez des points-virgules pour séparer les instructions et gardez-le lisible. Pour tout code de plus de ~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"Vidéo : {len(coll.get_videos())}")
EOF

Configuration

Lorsque l'utilisateur demande de "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 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, pas de carte de crédit).

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
vidéo = coll.upload(url="https://exemple.com/video.mp4")

# YouTube
vidéo = coll.upload(url="https://www.youtube.com/watch?v=VIDEO_ID")

# Fichier local
vidéo = coll.upload(file_path="/chemin/vers/video.mp4")

Transcription + sous-titres

# force=True ignore l'erreur si la vidéo est déjà indexée
vidéo.index_spoken_words(force=True)
texte = vidéo.get_transcript_text()
url_flux = vidéo.add_subtitle()

Rechercher dans les vidéos

from videodb.exceptions import InvalidRequestError

vidéo.index_spoken_words(force=True)

# search() lève InvalidRequestError lorsqu'aucun résultat n'est trouvé.
# Toujours englober dans try/except et traiter "Aucun résultat trouvé" comme vide.
try:
    résultats = vidéo.search("démo produit")
    plans = résultats.get_shots()
    url_flux = résultats.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 de l'erreur.
try:
    id_index_scène = vidéo.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:
        id_index_scène = correspondance.group(1)
    else:
        raise

# Utilisez score_threshold pour filtrer le bruit de faible pertinence (recommandé : 0.3+)
try:
    résultats = vidéo.search(
        query="personne écrivant sur un tableau blanc",
        search_type=SearchType.semantic,
        index_type=IndexType.scene,
        scene_index_id=id_index_scène,
        score_threshold=0.3,
    )
    plans = résultats.get_shots()
    url_flux = résultats.compile()
except InvalidRequestError as e:
    if "No results found" in str(e):
        plans = []
    else:
        raise

Édition de chronologie

Important : Validez toujours les horodatages avant de construire une chronologie :

  • 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

chronologie = Timeline(conn)
chronologie.add_inline(VideoAsset(asset_id=vidéo.id, start=10, end=30))
chronologie.add_overlay(0, TextAsset(text="La Fin", duration=3, style=TextStyle(fontsize=36)))
url_flux = chronologie.generate_stream()

Transcoder une vidéo (changement de résolution / qualité)

from videodb import TranscodeMode, VideoConfig, AudioConfig

# Changez la résolution, la qualité ou le format d'image côté serveur
id_tâche = conn.transcode(
    source="https://exemple.com/video.mp4",
    callback_url="https://exemple.com/webhook",
    mode=TranscodeMode.economy,
    video_config=VideoConfig(resolution=720, quality=23, aspect_ratio="16:9"),
    audio_config=AudioConfig(mute=False),
)

Recadrer le format d'image (pour plateformes sociales)

Attention : reframe() est une opération lente côté serveur. Pour les longues vidéos, cela peut prendre plusieurs minutes et entraîner un délai d'attente. Bonnes pratiques :

  • Limitez-vous toujours à un court segment en utilisant start/end lorsque c'est possible
  • Pour les vidéos complètes, utilisez callback_url pour le traitement asynchrone
  • Rognez d'abord la vidéo sur une Timeline, puis recadrez le résultat plus court
from videodb import ReframeMode

# Toujours préférer le recadrage d'un court segment :
recadré = vidéo.reframe(start=0, end=60, target="vertical", mode=ReframeMode.smart)

# Recadrage asynchrone pour les vidéos complètes (retourne None, résultat via webhook) :
vidéo.reframe(target="vertical", callback_url="https://exemple.com/webhook")

# Préréglages : "vertical" (9:16), "square" (1:1), "landscape" (16:9)
recadré = vidéo.reframe(start=0, end=60, target="square")

# Dimensions personnalisées
recadré = vidéo.reframe(start=0, end=60, target={"width": 1280, "height": 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:
    vidéo = coll.upload(url="https://exemple.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ée
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 = [])
Délai d'attente de recadrageBloque indéfiniment sur les longues vidéosUtilisez start/end pour limiter le segment, ou passez callback_url pour l'asynchrone
Horodatages négatifs sur la chronologieProduit silencieusement un flux casséValidez toujours start >= 0 avant de créer VideoAsset
Échec de generate_video() / create_collection()Operation 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 lorsqu'un champ de mot de passe apparaît."
  • "Enregistre ma session et produis un résumé exploitable à la fin."
  • "Ingère ce fichier et retourne un lien de flux lisible."
  • "Indexe ce dossier et trouve chaque scène 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 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 prend en charge macOS uniquement.

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 fois que vous démarrez une nouvelle session de capture afin que les événements transcript 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

répertoire_événements = Path(os.environ.get("VIDEODB_EVENTS_DIR", Path.home() / ".local" / "state" / "videodb"))
fichier_événements = répertoire_événements / "videodb_events.jsonl"
événements = []

if fichier_événements.exists():
    with fichier_événements.open(encoding="utf-8") as handle:
        for ligne in handle:
            try:
                événements.append(json.loads(ligne))
            except json.JSONDecodeError:
                continue

transcriptions = [e["data"]["text"] for e in événements if e.get("channel") == "transcript"]
seuil = time.time() - 300
récents_visuels = [
    e for e in événements
    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 des 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 : rognage, combinaison d'extraits, superposition audio ou musique, ajout de sous-titres, superpositions texte/image, transcodage, changements de résolution, conversion de format d'image, redimensionnement pour les exigences de la plateforme, transcription et génération de médias. Ne recourez aux outils locaux que pour les opérations listées dans la section Limitations de reference/editor.md (transitions, changements de vitesse, recadrage/zoom, étalonnage des couleurs, mixage de 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(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éoAudioAsset sur une Timeline
Besoin d'ajouter des sous-titresvideo.add_subtitle() ou CaptionAsset
Besoin de combiner/rogner 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 fourni localement sous skills/videodb/reference/. Utilisez les copies locales ci-dessus au lieu de suivre des liens de dépôts externes lors de l'exécution.

Individual skills in this repo

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

Skills associés