Communitygithub.com

DekaPrayoga/AurixAgent

Veja, entenda e aja em vídeo e áudio. Veja: ingira de arquivos locais, URLs, feeds ao vivo/RTSP ou grave a área de trabalho; retorne contexto em tempo real e links de stream reproduzíveis. Entenda: extraia quadros, construa índices visuais/semânticos/temporais e pesquise momentos com timestamps e clipes automáticos. Aja: transcodifique e normalize (codec, fps, resolução, proporção), realize edições na linha do tempo (legendas, sobreposições de texto/imagem, marca, sobreposições de áudio, dublagem, tradução), gere ativos de mídia (imagem, áudio, vídeo) e crie alertas em tempo real para eventos de streams ao vivo ou captura de área de trabalho.

O que é AurixAgent?

A skill AurixAgent (VideoDB) fornece um conjunto completo de percepção, memória e ações para fluxos de trabalho de vídeo e áudio. Ela permite que agentes de IA ingiram conteúdo de diversas fontes (arquivos locais, URLs, YouTube, RTSP, tela/áudio do desktop), retornando links de stream reproduzíveis. A skill constrói índices visuais, semânticos e de fala para pesquisa de momento exato com timestamps e geração automática de clipes. Para edição, oferece transcodificação server-side, reframing de proporção, e composição programática (legendas, sobreposições, áudio, efeitos) via Timeline. A captura de desktop (macOS) permite sessões ao vivo com eventos em tempo real (transcrição e índice visual) e sumarização pós-sessão. A integração é feita pelo SDK Python `videodb`, usando a chave `VIDEO_DB_API_KEY`. O agente deve sempre usar as APIs do VideoDB para operações suportadas (corte, combinação, sobreposição, transcodificação), evitando ferramentas locais como ffmpeg, exceto para casos listados como limitações. A referência completa está em arquivos locais Markdown na pasta `reference/`.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/DekaPrayoga/AurixAgent/tree/HEAD/skills/videodb

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Skill VideoDB

Percepção + memória + ações para vídeo, streams ao vivo e sessões de desktop.

Quando usar

Percepção de Desktop

  • Iniciar/parar uma sessão de desktop capturando tela, microfone e áudio do sistema
  • Transmitir contexto ao vivo e armazenar memória episódica de sessão
  • Executar alertas/gatilhos em tempo real sobre o que é falado e o que acontece na tela
  • Produzir sumários de sessão, uma linha do tempo pesquisável e links de evidência reproduzíveis

Ingestão de vídeo + stream

  • Ingerir um arquivo ou URL e retornar um link de stream web reproduzível
  • Transcodificar/normalizar: codec, bitrate, fps, resolução, proporção

Indexar + pesquisar (timestamps + evidência)

  • Construir índices visuais, falados e por palavras-chave
  • Pesquisar e retornar momentos exatos com timestamps e evidência reproduzível
  • Criar clipes automaticamente a partir dos resultados da pesquisa

Edição de linha do tempo + geração

  • Legendas: gerar, traduzir, queimar
  • Sobreposições: texto/imagem/marca, legendas em movimento
  • Áudio: música de fundo, narração, dublagem
  • Composição programática e exportações via operações de linha do tempo

Streams ao vivo (RTSP) + monitoramento

  • Conectar feeds RTSP/ao vivo
  • Executar compreensão visual e falada em tempo real e emitir eventos/alertas para fluxos de monitoramento

Como funciona

Entradas comuns

  • Caminho de arquivo local, URL pública ou URL RTSP
  • Solicitação de captura de desktop: iniciar / parar / resumir sessão
  • Operações desejadas: obter contexto para compreensão, especificação de transcodificação, especificação de índice, consulta de pesquisa, intervalos de clipe, edições de linha do tempo, regras de alerta

Saídas comuns

  • URL do stream
  • Resultados de pesquisa com timestamps e links de evidência
  • Ativos gerados: legendas, áudio, imagens, clipes
  • Cargas de evento/alerta para streams ao vivo
  • Sumários de sessão de desktop e entradas de memória

Executando código Python

Antes de executar qualquer código do VideoDB, mude para o diretório do projeto e carregue as variáveis de ambiente:

from dotenv import load_dotenv
load_dotenv(".env")

import videodb
conn = videodb.connect()

Isso lê VIDEO_DB_API_KEY de:

  1. Ambiente (se já exportado)
  2. Arquivo .env do projeto no diretório atual

Se a chave estiver faltando, videodb.connect() levanta AuthenticationError automaticamente.

NÃO escreva um arquivo de script quando um comando inline curto funcionar.

Ao escrever Python inline (python -c "..."), use sempre código formatado corretamente — use ponto e vírgula para separar instruções e mantenha legível. Para algo mais longo que ~3 instruções, use um heredoc:

python << 'EOF'
from dotenv import load_dotenv
load_dotenv(".env")

import videodb
conn = videodb.connect()
coll = conn.get_collection()
print(f"Vídeos: {len(coll.get_videos())}")
EOF

Configuração

Quando o usuário pedir para "configurar videodb" ou similar:

1. Instalar SDK

pip install "videodb[capture]" python-dotenv

Se videodb[capture] falhar no Linux, instale sem o extra de captura:

pip install videodb python-dotenv

2. Configurar chave de API

O usuário deve definir VIDEO_DB_API_KEY usando um dos métodos:

  • Exportar no terminal (antes de iniciar o Claude): export VIDEO_DB_API_KEY=sua-chave
  • Arquivo .env do projeto: Salve VIDEO_DB_API_KEY=sua-chave no arquivo .env do projeto

Obtenha uma chave de API gratuita em console.videodb.io (50 uploads grátis, sem cartão de crédito).

NÃO leia, escreva ou manipule a chave de API você mesmo. Sempre deixe o usuário configurá-la.

Referência rápida

Fazer upload de mídia

# URL
video = coll.upload(url="https://exemplo.com/video.mp4")

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

# Arquivo local
video = coll.upload(file_path="/caminho/para/video.mp4")

Transcrição + legenda

# force=True pula o erro se o vídeo já estiver indexado
video.index_spoken_words(force=True)
text = video.get_transcript_text()
stream_url = video.add_subtitle()

Pesquisar dentro de vídeos

from videodb.exceptions import InvalidRequestError

video.index_spoken_words(force=True)

# search() levanta InvalidRequestError quando nenhum resultado é encontrado.
# Sempre envolva em try/except e trate "Nenhum resultado encontrado" como vazio.
try:
    results = video.search("demonstração de produto")
    shots = results.get_shots()
    stream_url = results.compile()
except InvalidRequestError as e:
    if "No results found" in str(e):
        shots = []
    else:
        raise

Pesquisa de cena

import re
from videodb import SearchType, IndexType, SceneExtractionType
from videodb.exceptions import InvalidRequestError

# index_scenes() não tem parâmetro force — ele levanta um erro se um índice
# de cena já existir. Extraia o ID do índice existente do erro.
try:
    scene_index_id = video.index_scenes(
        extraction_type=SceneExtractionType.shot_based,
        prompt="Descreva o conteúdo visual nesta cena.",
    )
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

# Use score_threshold para filtrar ruído de baixa relevância (recomendado: 0.3+)
try:
    results = video.search(
        query="pessoa escrevendo em um quadro branco",
        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

Edição de linha do tempo

Importante: Sempre valide timestamps antes de construir uma linha do tempo:

  • start deve ser >= 0 (valores negativos são aceitos silenciosamente, mas produzem saída quebrada)
  • start deve ser < end
  • end deve ser <= 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="O Fim", duration=3, style=TextStyle(fontsize=36)))
stream_url = timeline.generate_stream()

Transcodificar vídeo (mudança de resolução/qualidade)

from videodb import TranscodeMode, VideoConfig, AudioConfig

# Mude resolução, qualidade ou proporção no servidor
job_id = conn.transcode(
    source="https://exemplo.com/video.mp4",
    callback_url="https://exemplo.com/webhook",
    mode=TranscodeMode.economy,
    video_config=VideoConfig(resolution=720, quality=23, aspect_ratio="16:9"),
    audio_config=AudioConfig(mute=False),
)

Reenquadrar proporção (para plataformas sociais)

Aviso: reframe() é uma operação lenta no servidor. Para vídeos longos pode levar vários minutos e pode expirar. Melhores práticas:

  • Sempre limite a um segmento curto usando start/end quando possível
  • Para vídeos completos, use callback_url para processamento assíncrono
  • Apare o vídeo em uma Timeline primeiro, depois reenquadre o resultado mais curto
from videodb import ReframeMode

# Sempre prefira reenquadrar um segmento curto:
reframed = video.reframe(start=0, end=60, target="vertical", mode=ReframeMode.smart)

# Reenquadramento assíncrono para vídeos completos (retorna None, resultado via webhook):
video.reframe(target="vertical", callback_url="https://exemplo.com/webhook")

# Predefinições: "vertical" (9:16), "square" (1:1), "landscape" (16:9)
reframed = video.reframe(start=0, end=60, target="square")

# Dimensões personalizadas
reframed = video.reframe(start=0, end=60, target={"width": 1280, "height": 720})

Mídia generativa

image = coll.generate_image(
    prompt="um pôr do sol sobre montanhas",
    aspect_ratio="16:9",
)

Tratamento de erros

from videodb.exceptions import AuthenticationError, InvalidRequestError

try:
    conn = videodb.connect()
except AuthenticationError:
    print("Verifique sua VIDEO_DB_API_KEY")

try:
    video = coll.upload(url="https://exemplo.com/video.mp4")
except InvalidRequestError as e:
    print(f"Falha no upload: {e}")

Armadilhas comuns

CenárioMensagem de erroSolução
Indexar um vídeo já indexadoSpoken word index for video already existsUse video.index_spoken_words(force=True) para pular se já indexado
Índice de cena já existeScene index with id XXXX already existsExtraia o scene_index_id existente do erro com re.search(r"id\s+([a-f0-9]+)", str(e))
Pesquisa não encontra correspondênciasInvalidRequestError: No results foundCapture a exceção e trate como resultados vazios (shots = [])
Reenquadramento expiraBloqueia indefinidamente em vídeos longosUse start/end para limitar o segmento, ou passe callback_url para assíncrono
Timestamps negativos na TimelineProduz silenciosamente um stream quebradoSempre valide start >= 0 antes de criar VideoAsset
generate_video() / create_collection() falhaOperation not allowed ou maximum limitRecursos limitados por plano — informe o usuário sobre os limites do plano

Exemplos

Prompts canônicos

  • "Iniciar captura de desktop e alertar quando um campo de senha aparecer."
  • "Gravar minha sessão e produzir um resumo acionável quando terminar."
  • "Ingerir este arquivo e retornar um link de stream reproduzível."
  • "Indexar esta pasta e encontrar cada cena com pessoas, retornar timestamps."
  • "Gerar legendas, queimá-las e adicionar música de fundo suave."
  • "Conectar esta URL RTSP e alertar quando uma pessoa entrar na zona."

Gravação de Tela (Captura de Desktop)

Use ws_listener.py para capturar eventos WebSocket durante sessões de gravação. A captura de desktop suporta macOS apenas.

Início rápido

  1. Escolher diretório de estado: STATE_DIR="${VIDEODB_EVENTS_DIR:-$HOME/.local/state/videodb}"
  2. Iniciar listener: VIDEODB_EVENTS_DIR="$STATE_DIR" python scripts/ws_listener.py --clear "$STATE_DIR" &
  3. Obter ID WebSocket: cat "$STATE_DIR/videodb_ws_id"
  4. Executar código de captura (veja reference/capture.md para o fluxo completo)
  5. Eventos escritos em: $STATE_DIR/videodb_events.jsonl

Use --clear sempre que iniciar uma nova execução de captura para que eventos de transcrição e visuais antigos não vazem para a nova sessão.

Consultar Eventos

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
]

Documentação adicional

A documentação de referência está no diretório reference/ adjacente a este arquivo SKILL.md. Use a ferramenta Glob para localizá-la se necessário.

Não use ffmpeg, moviepy ou ferramentas de codificação local quando o VideoDB suportar a operação. Os seguintes são todos tratados no servidor pelo VideoDB — corte, combinação de clipes, sobreposição de áudio ou música, adição de legendas, sobreposições de texto/imagem, transcodificação, mudanças de resolução, conversão de proporção, redimensionamento para requisitos de plataforma, transcrição e geração de mídia. Recorra a ferramentas locais apenas para operações listadas em Limitações em reference/editor.md (transições, mudanças de velocidade, corte/zoom, correção de cor, mixagem de volume).

Quando usar o quê

ProblemaSolução VideoDB
Plataforma rejeita proporção ou resolução do vídeovideo.reframe() ou conn.transcode() com VideoConfig
Precisa redimensionar vídeo para Twitter/Instagram/TikTokvideo.reframe(target="vertical") ou target="square"
Precisa mudar resolução (ex: 1080p → 720p)conn.transcode() com VideoConfig(resolution=720)
Precisa sobrepor áudio/música no vídeoAudioAsset em uma Timeline
Precisa adicionar legendasvideo.add_subtitle() ou CaptionAsset
Precisa combinar/cortar clipesVideoAsset em uma Timeline
Precisa gerar narração, música ou SFXcoll.generate_voice(), generate_music(), generate_sound_effect()

Proveniência

O material de referência para esta skill é fornecido localmente em skills/videodb/reference/. Use as cópias locais acima em vez de seguir links de repositórios externos em tempo de execução.

Individual skills in this repo

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

Habilidades Relacionadas