O que watch faz?
Você não tem uma entrada de vídeo; esta habilidade fornece uma. Um script Python obtém as legendas primeiro, opcionalmente baixa o vídeo, extrai quadros como JPEGs (com consciência de cena, ou quadros-chave rápidos no detalhe efficient), obtém uma transcrição com timestamps (primeiro legendas nativas, depois API Whisper como fallback) e imprime os caminhos dos quadros. Em seguida, você Lê cada caminho de quadro para ver as imagens e combina-as com a transcrição para responder ao usuário.
Resolver SKILL_DIR (faça isso antes de qualquer comando)
Cada comando python3 ... abaixo executa um script incluído em SKILL_DIR/scripts/. Defina SKILL_DIR como o caminho absoluto do diretório que contém ESTE SKILL.md que você acabou de Ler — seu executor informou esse caminho no resultado da Leitura. Os scripts são sempre um irmão direto deste arquivo (SKILL_DIR/scripts/watch.py), em qualquer estrutura de instalação:
Ler ~/.claude/plugins/cache/claude-video/watch/<ver>/skills/watch/SKILL.md → SKILL_DIR=…/skills/watch
Ler ~/.codex/skills/watch/SKILL.md → SKILL_DIR=~/.codex/skills/watch
Ler ~/.agents/skills/watch/SKILL.md → SKILL_DIR=~/.agents/skills/watch
Substitua esse caminho literal por ${SKILL_DIR} em cada comando. Isso funciona em qualquer executor (Claude Code, Codex, Cursor, Gemini CLI, …) sem depender de nenhuma variável de ambiente específica do executor. Faça a verificação uma vez no início de uma execução:
SKILL_DIR="<caminho absoluto do diretório que contém o SKILL.md que você Leu>"
if [ ! -f "$SKILL_DIR/scripts/watch.py" ]; then
echo "ERRO: scripts/watch.py não encontrado em SKILL_DIR=$SKILL_DIR" >&2
echo "Verifique novamente o diretório do SKILL.md que você Leu e substitua-o como SKILL_DIR." >&2
exit 1
fi
Etapa 0 — Verificação pré-configuração (executada a cada chamada /watch, silenciosa em caso de sucesso)
Interpretador Python: cada comando python3 ... nesta habilidade é para macOS/Linux. No Windows, substitua por python — o comando python3 no Windows é um atalho da Microsoft Store e não executará o script.
Na primeira chamada /watch em uma sessão, use a verificação estruturada para detectar configuração de primeira execução:
python3 "${SKILL_DIR}/scripts/setup.py" --json
Ramifique com base em dois campos:
can_proceed: trueefirst_run: false→ a configuração já está concluída (o usuário pode ter pulado deliberadamente uma chave Whisper — isso é permitido). Prossiga para a Etapa 1 sem comentários.first_run: true→ configuração genuína de primeira vez. Faça isso na ordem:- Se
missing_binariesnão estiver vazio, execute o instalador primeiro (ele instala automaticamente no macOS / imprime comandos em outros lugares — veja abaixo) e confirme se os binários foram instalados. Não pule isso e vá para as preferências. - Execute o instalador novamente, se necessário, para que ele crie o modelo
~/.config/watch/.env(ele só escreve o modelo quando o arquivo está ausente, então deixe-o criar o arquivo antes de você escrever qualquer valor nele). - Incentive uma chave da API Whisper e faça as perguntas de preferência de exibição abaixo, depois escreva os valores selecionados em
~/.config/watch/.enve definaSETUP_COMPLETE=true.
- Se
can_proceed: falseefirst_run: false→ a configuração foi concluída antes, mas o ambiente regrediu (por exemplo,missing_binariesapós uma alteração no sistema operacional). Execute o instalador para corrigir e prossiga. Não pergunte novamente as preferências.
Uma chave Whisper ausente é incentivada a ser corrigida, não obrigatória: em uma primeira execução genuína, status lerá needs_key mesmo quando os binários estiverem presentes — esse é seu sinal para incentivar uma chave, não um bloqueio.
Em chamadas /watch subsequentes na mesma sessão, use a verificação silenciosa:
python3 "${SKILL_DIR}/scripts/setup.py" --check
Isso é uma consulta de <100ms. Saída 0 significa que /watch pode ser executado — isso inclui um usuário que concluiu a configuração sem uma chave Whisper (sem chave é permitido). Na saída 0, o script não emite nada — prossiga para a Etapa 1 sem comentários. NÃO anuncie "configuração concluída" ao usuário — ele não precisa de uma mensagem de status a cada rodada. A única saída visível ao usuário aceitável da Etapa 0 é quando uma correção é necessária.
Em saída diferente de zero, siga a tabela:
| Saída | Significado | Ação |
|---|---|---|
2 | Binários ausentes (ffmpeg / ffprobe / yt-dlp) | Execute o instalador |
3 | Primeira execução genuína sem chave da API Whisper | Execute o instalador para criar .env e incentive uma chave (o usuário pode recusar — prossiga com --no-whisper) |
4 | Ambos ausentes | Execute o instalador e incentive uma chave |
A saída 3 só é acionada antes de o usuário concluir a configuração. Quando SETUP_COMPLETE=true é escrito, uma instalação sem chave retorna saída 0 e nunca é questionada novamente.
O instalador é idempotente — seguro para reexecutar:
python3 "${SKILL_DIR}/scripts/setup.py"
No macOS com Homebrew, ele instala automaticamente ffmpeg e yt-dlp. No Linux/Windows, ele imprime os comandos de instalação exatos para o usuário executar. Ele cria ~/.config/watch/.env com placeholders comentados e configurações de exibição padrão com permissões 0600.
Se uma chave da API ainda estiver ausente após a instalação: use AskUserQuestion para perguntar ao usuário se ele tem uma chave da API Groq (preferida — mais barata, mais rápida) ou uma chave OpenAI. Depois, escreva-a em ~/.config/watch/.env — defina a linha correspondente GROQ_API_KEY=... ou OPENAI_API_KEY=.... Se ele não quiser configurar o Whisper, prossiga com --no-whisper e informe que vídeos sem legendas nativas retornarão apenas quadros.
Preferência de exibição na primeira execução: após o instalador criar o modelo ~/.config/watch/.env, use AskUserQuestion para fazer uma pergunta:
- Detalhe padrão (um dial). Apresente estas opções como opções
AskUserQuestionnesta ordem exata — da mais leve à mais pesada — e mantenha(recomendado)embalancedmesmo que não seja o primeiro (não reordene para colocar a opção recomendada em primeiro):transcript— sem quadros, apenas transcrição (ignora o download do vídeo quando as legendas existem).efficient— passagem rápida de quadros-chave (limite de 50).balanced(recomendado) — quadros com detecção de cena (limite de 100, padrão).token-burner— detecção de cena, sem limite (máxima fidelidade; alto custo de tokens).
Escreva a resposta diretamente em ~/.config/watch/.env definindo a chave simples em sua própria linha — nenhum comentário inline após (um # nota após o valor pode quebrar a análise):
WATCH_DETAIL=balanced
Use o valor selecionado pelo usuário. Se ele pular a pergunta, mantenha o padrão recomendado. Uma vez que as dependências, a escolha da chave da API e esta preferência forem tratadas, escreva ou atualize SETUP_COMPLETE=true no mesmo arquivo. Não faça esta pergunta de preferência novamente quando SETUP_COMPLETE=true.
Modo estruturado (opcional): python3 "${SKILL_DIR}/scripts/setup.py" --json emite {status, can_proceed, first_run, setup_complete, missing_binaries, whisper_backend, has_api_key, config_file, watch_detail, platform} onde status é um de ready | needs_install | needs_key | needs_install_and_key. status descreve o estado ideal (uma chave é incentivada, então uma primeira execução sem chave lê needs_key); can_proceed é a porta operacional (binários presentes E uma chave está definida OU a configuração já foi concluída). Ramifique com base em can_proceed/first_run para decidir se deve executar; use status para decidir o que incentivar.
Dentro de uma única sessão, você pode pular a Etapa 0 em chamadas /watch subsequentes — uma vez que --check retornou 0, nada no ambiente muda entre as rodadas.
Quando usar
- O usuário cola uma URL de vídeo (YouTube, Vimeo, X, TikTok, clipe do Twitch, a maioria dos sites suportados pelo yt-dlp) e pergunta sobre ele.
- O usuário aponta para um arquivo de vídeo local (
.mp4,.mov,.mkv,.webm, etc.) e pergunta sobre ele. - O usuário digita
/watch <url-ou-caminho> [pergunta].
Limites recomendados
- Melhor precisão: vídeos com menos de 10 minutos. A cobertura de quadros é inversamente proporcional à duração.
- Limite de taxa universal: 2 qps. O script nunca amostra mais rápido que 2 quadros por segundo, mesmo quando um orçamento ou
--fpssugeriria mais. - O limite de quadros é definido pelo modo de detalhe (
WATCH_DETAILem~/.config/watch/.env, ou--detail), não por um limite global único:transcript→ sem quadrosefficient→ até 50 (quadros-chave)balanced(padrão) → até 100 (detecção de cena)token-burner→ sem limite (detecção de cena; um aviso suave é impresso após 250 quadros)--max-frames Nsubstitui qualquer limite que o modo usaria.
- Orçamento de quadros para vídeo completo por duração. O custo de tokens cresce com o número de quadros, então o script define um orçamento por duração. Este orçamento define o fps e o fallback de amostragem uniforme; a seleção com detecção de cena pode preencher até o limite de detalhe acima, o que for menor:
- ≤30s → ~12-30 quadros
- 30s-1min → ~40 quadros
- 1-3min → ~60 quadros
- 3-10min → ~80 quadros
-
10min → até o limite de detalhe, espaçados esparsamente (aviso impresso)
- Se o usuário fornecer um vídeo longo, considere perguntar se ele deseja uma seção específica antes de queimar tokens em uma varredura esparsa.
Como invocar
Etapa 1 — analise a entrada do usuário. Separe a origem do vídeo (URL ou caminho) de qualquer pergunta que o usuário fez. Exemplo: /watch https://youtu.be/abc em que idioma está isso? → origem = https://youtu.be/abc, pergunta = em que idioma está isso?.
Etapa 2 — execute o script de exibição. Passe a origem literalmente. Não escape por shell você mesmo além das aspas normais:
python3 "${SKILL_DIR}/scripts/watch.py" "<origem>"
Flags opcionais:
--detail transcript|efficient|balanced|token-burner— dial de fidelidade/velocidade.transcript= sem quadros (apenas transcrição, ignora o download do vídeo quando as legendas existem);efficient= quadros-chave rápidos (limite 50);balanced= quadros com detecção de cena (limite 100);token-burner= detecção de cena, sem limite.--start T/--end T— focar em uma seção. AceitaSS,MM:SSouHH:MM:SS. Quando qualquer um é definido, o fps é dimensionado automaticamente para mais denso (veja "Focando em uma seção" abaixo).--timestamps T1,T2,…— capturar um quadro em cada um desses timestamps absolutos (SS,MM:SSouHH:MM:SS). Use isso após ler a transcrição para capturar momentos déiticos que o apresentador sinaliza ("olhe aqui", "como você pode ver", "note isso") que a seleção visual sozinha pode perder. Veja "Quadros com dica de transcrição" abaixo.--max-frames N— substituir o limite predefinido para um orçamento de tokens mais restrito (por exemplo,--max-frames 40)--resolution W— alterar a largura do quadro em px (padrão 512; aumente para 1024 apenas se o usuário precisar ler texto na tela)--fps F— substituir o fps automático (limitado a no máximo 2 qps)--out-dir DIR— manter arquivos de trabalho em algum lugar específico (padrão: um diretório tmp gerado automaticamente)--whisper groq|openai— forçar um backend Whisper específico (padrão: preferir Groq se ambas as chaves existirem)--no-whisper— desabilitar completamente o fallback do Whisper (apenas quadros se não houver legendas)--no-dedup— manter quadros quase duplicados. Por padrão, uma passagem de delta de quadro descarta quadros visualmente quase idênticos ao anterior mantido (slides parados, gravações de tela estáticas, vídeo pausado) para que o orçamento de quadros vá para conteúdo distinto; a linha Quadros do relatório observa quantos foram descartados. Passe isso apenas se o usuário precisar de cada quadro amostrado (por exemplo, julgando movimento sutil quadro a quadro).
Focando em uma seção (taxa de quadros mais alta)
Quando o usuário pergunta sobre um momento específico — "o que acontece na marca de 2 minutos?", "amplie de 0:45 a 1:00", "os primeiros 10 segundos" — passe --start e/ou --end. O script muda para orçamentos de modo focado, que são mais densos que os orçamentos de vídeo completo (ainda limitados a 2 qps e ainda limitados pelo limite do modo de detalhe — as contagens abaixo assumem o limite padrão balanced de 100; efficient atinge no máximo 50):
- ≤5s → 2 qps (até 10 quadros)
- 5-15s → 2 qps (até 30 quadros)
- 15-30s → ~2 qps (até 60 quadros)
- 30-60s → ~1,3 qps (até 80 quadros)
- 60-180s → ~0,6 qps (100 quadros, limitado)
O modo focado é a escolha certa para:
- Qualquer momento/intervalo que o usuário nomeie explicitamente ("por volta de 2:30", "a introdução", "os últimos 30 segundos").
- Qualquer vídeo com mais de ~10 minutos onde a pergunta do usuário seja sobre uma parte específica — executar o modo focado na seção relevante é muito mais útil do que uma varredura esparsa do todo.
- Reexecuções após uma varredura completa não terem detalhes suficientes em alguma região.
A transcrição é automaticamente filtrada para o mesmo intervalo. Os timestamps dos quadros são absolutos (linha do tempo real do vídeo, não deslocados do início).
Exemplos:
# Últimos 10 segundos de um vídeo de 1 minuto
python3 "${SKILL_DIR}/scripts/watch.py" video.mp4 --start 50 --end 60
# Amplie 2:15 → 2:45 a 2 qps (60 quadros)
python3 "${SKILL_DIR}/scripts/watch.py" "$URL" --start 2:15 --end 2:45 --fps 2
# De 1h12m até o final do vídeo
python3 "${SKILL_DIR}/scripts/watch.py" "$URL" --start 1:12:00
Etapa 3 — Leia cada caminho de quadro que o script listar. A ferramenta Leitura renderiza JPEGs diretamente como imagens para você. Leia todos os quadros em uma única mensagem (chamadas de ferramentas paralelas) para que você os veja juntos. Os quadros estão em ordem cronológica com um timestamp t=MM:SS para que você possa alinhá-los à transcrição.
Etapa 4 — responda ao usuário. Agora você tem dois fluxos de evidência:
- Quadros — o que está na tela em cada timestamp
- Transcrição — o que é dito em cada timestamp. O cabeçalho do relatório mostra a origem (
captions= yt-dlp obteve legendas nativas;whisper (groq)ouwhisper (openai)= transcrito pela API).
Se o usuário fez uma pergunta específica, responda-a diretamente citando timestamps. Se ele não perguntou nada, resuma o que acontece no vídeo — estrutura, momentos-chave, elementos visuais notáveis, conteúdo falado.
Isso vale também para o detalhe transcript: mesmo sem quadros, produza um resumo como os outros modos — não cole a transcrição completa no chat. Sintetize estrutura, momentos-chave e conteúdo falado com timestamps; cite apenas as linhas que importam. Ofereça a transcrição bruta apenas se o usuário explicitamente solicitá-la.
Etapa 5 — limpeza. O script imprime um diretório de trabalho no final. Se o usuário não for fazer perguntas de acompanhamento sobre este vídeo, exclua-o com rm -rf <dir>. Se ele puder, mantenha-o no lugar.
Detalhe e quadros
O comportamento padrão vem de ~/.config/watch/.env:
WATCH_DETAIL=transcript|efficient|balanced|token-burner(padrão:balanced)
Em balanced, o script usa detecção de cena para selecionar até 100 quadros. A detecção de cena encontra pontos de edição reais no vídeo (cortes, transições, mudanças de slide) e extrai um quadro por cena, dando cobertura aos cortes reais em vez de amostrar em intervalos fixos. Abaixo de 100 cenas, todos os quadros de cena são mantidos; acima disso, a amostragem uniforme é aplicada sobre o conjunto de cenas para retornar 100 quadros
(continua…)
Leitura adicional
- Repositório de scripts watch.py e setup.py — código-fonte e instalação manual
- Documentação do yt-dlp — sites suportados e opções de formato
- Documentação do ffmpeg — extração e dimensionamento de quadros
- Documentação da API Whisper (OpenAI)
- Documentação da API Groq