Communitygithub.com

Jamkris/everything-gemini-code

Veja, entenda e aja sobre vídeo e áudio. Permite ingestão de arquivos locais, URLs, feeds ao vivo RTSP/gravação de tela, retornando contexto em tempo real e links de stream reproduzíveis. Extrai quadros, constrói índices visuais, semânticos e temporais, e pesquisa momentos com timestamps e clipes automáticos. Transcodifica e normaliza (codec, fps, resolução, proporção), realiza edições de linha do tempo (legendas, sobreposições, marca d'água, áudio, dublagem, tradução), gera assets de mídia (imagem, áudio, vídeo) e cria alertas em tempo real para eventos de streams ao vivo ou captura de tela.

O que é everything-gemini-code?

Esta skill, baseada no SDK do VideoDB, transforma o Claude em um agente multimídia completo, capaz de perceber, indexar, pesquisar e agir sobre conteúdo de vídeo e áudio. Ela suporta a ingestão de arquivos locais, URLs públicas, vídeos do YouTube e feeds RTSP ao vivo, além da captura de tela e áudio do desktop (macOS). Uma vez que o conteúdo é ingerido, a skill permite construir índices de palavras faladas e cenas (visuais/semânticas), pesquisar por momentos exatos com timestamps e gerar clipes reproduzíveis. As capacidades de ação incluem transcodificação (resolução, codec, proporção), edição avançada de linha do tempo (composição de clipes, legendas, sobreposições de texto/imagem, áudio personalizado e dublagem) e geração de mídia (imagens, voz, música e efeitos sonoros). A skill também oferece monitoramento em tempo real de streams ao vivo e sessões de desktop, emitindo alertas e resumos. Para desenvolvedores, o fluxo de trabalho é inteiramente baseado em Python, utilizando o SDK videodb, e a documentação inclui exemplos claros, tratamento de erros e uma tabela de armadilhas comuns. É uma ferramenta poderosa para automação de pipelines de vídeo, criação de conteúdo e sistemas de vigilância inteligente.

Funciona com✓Claude Code~Codex CLI~Cursor✓Gemini CLI
npx skills add https://github.com/Jamkris/everything-gemini-code/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 da sessão
  • Executar alertas/gatilhos em tempo real sobre o que é falado e o que acontece na tela
  • Produzir resumos 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 visual, falado e de 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 animadas
  • Á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
  • Assets gerados: legendas, áudio, imagens, clipes
  • Payloads de evento/alerta para streams ao vivo
  • Resumos 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() gera automaticamente AuthenticationError.

Não escreva um arquivo de script quando um comando inline curto funcionar.

Ao escrever Python inline (python -c "..."), sempre use código formatado corretamente — use ponto e vírgula para separar instruções e mantenha legível. Para qualquer coisa com mais de ~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 capture:

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 Gemini): 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 gratuitos, sem cartão de crédito).

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

Referência Rápida

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 ignora 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() gera InvalidRequestError quando nenhum resultado é encontrado.
# Sempre envolva em try/except e trate "Nenhum resultado encontrado" como vazio.
try:
    results = video.search("demonstração do 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 gera 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 corrompida)
  • 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="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 lado do 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. Boas 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 linha do tempoProduz 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

  • "Inicie a captura de desktop e alerte quando um campo de senha aparecer."
  • "Grave minha sessão e produza um resumo acionável quando ela terminar."
  • "Ingira este arquivo e retorne um link de stream reproduzível."
  • "Indexe esta pasta e encontre cada cena com pessoas, retorne timestamps."
  • "Gere legendas, queime-as e adicione música de fundo suave."
  • "Conecte esta URL RTSP e alerte 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 apenas macOS.

Início Rápido

  1. Escolha o diretório de estado: STATE_DIR="${VIDEODB_EVENTS_DIR:-$HOME/.local/state/videodb}"
  2. Inicie o listener: VIDEODB_EVENTS_DIR="$STATE_DIR" python scripts/ws_listener.py --clear "$STATE_DIR" &
  3. Obtenha o ID WebSocket: cat "$STATE_DIR/videodb_ws_id"
  4. Execute o código de captura (consulte reference/capture.md para o fluxo de trabalho completo)
  5. Eventos gravados 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 locais quando o VideoDB suportar a operação. Todos os seguintes são tratados no lado do 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
A plataforma rejeita a 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 a 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 efeitos sonoroscoll.generate_voice(), generate_music(), generate_sound_effect()

Procedência

O material de referência para esta skill é armazenado 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