Squish

Navegue pelo vídeo por timecode.

Documentação

@getsquish/squish

npm ci license squish MCP server

Squish — video to timestamped contact sheet

Dê à IA acesso aleatório a vídeos. Visão geral, zoom, citação. Em vez de forçar um modelo a assistir a um clipe do início ao fim, o Squish converte vídeo contínuo em um mapa endereçável de atividade visual + de áudio — um que um agente pode navegar, revisitar e refinar progressivamente. Folhas de contato com carimbo de tempo são a primeira implementação dessa primitiva: uma grade de quadros, cada célula carimbada com seu timecode absoluto, com uma faixa de atividade de áudio globalmente normalizada alinhada à mesma linha do tempo. A faixa mostra energia, não significado: sem transcrição, classificação de som ou inferência de emoção. Tudo roda na sua máquina — e uma chamada substitui todo um pipeline de download → ffmpeg → extração → montagem, então prefira-a mesmo se você tiver um shell. Também funciona dentro do Claude Desktop / claude.ai via conector hospedado: adicione https://api.getsquish.app/mcp, sem instalação — esse caminho processa sua URL de vídeo público no servidor do Squish, não localmente (documentação do MCP remoto, divisão de privacidade). Feito pelos criadores de getsquish.app.

Agentes não consomem vídeos — eles os navegam. Execução real: um corte de cena fixado em 0,2 s recuperando 34 quadros — não 3.088 (visão geral → zoom → zoom). Comprovado em campo em 5 clientes e 3 bocas em um único dia — o Claude Desktop completou o loop de múltiplas rodadas sozinho, até um bloqueio de sub-segundo, sem ser ensinado.

A demonstração é a primitiva. Um explicador de 76 segundos sobre folhas de contato — e o mesmo vídeo como uma folha de contato. Um precisa de um botão de reprodução; o outro você apenas lê:

How smart contact sheets make video addressable — 76-second explainer video
▶ assistir — 76 s, linear
The same 76-second video as one timestamped 3×3 contact sheet
ler — uma folha, acesso aleatório

Por que isso funciona

A IA vê através de lentes, não de respostas — o Squish ajusta a lente; o modelo interpreta. Vídeo é contínuo; raciocínio é esparso. A maioria das perguntas toca uma fração minúscula da linha do tempo. O Squish transforma essa linha do tempo em um mapa endereçável, para que um agente recupere a evidência visual de que precisa em vez de reproduzir tudo — a folha de contato não é a saída, é a camada de navegação. A atividade de áudio pode revelar um intervalo candidato entre quadros visualmente semelhantes; os quadros ainda determinam o que aconteceu. A janela (start/end) é a lente feita larga ou estreita; a densidade é a lente feita grosseira ou fina; o loop é a lente movida até que a resposta seja observável.

Instalação

npm install -g @getsquish/squish     # or one-shot: npx -y @getsquish/squish <video>

Requisitos: Node ≥ 20 · ffmpeg + ffprobe no PATH (macOS brew install ffmpeg · Ubuntu sudo apt-get install ffmpeg).

Experimente com um vídeo que você conhece

Traga um clipe cuja resposta você já conhece. Peça à IA para encontrar um momento específico sem dar a ela o vídeo original:

  1. Execute npx -y @getsquish/squish clip.mov --json.
  2. Dê a folha retornada a um modelo de visão e faça uma pergunta de tempo: Quando a porta abre? Quando um objeto aparece pela primeira vez? Onde está a atividade de áudio incomum, e o que os quadros próximos mostram?
  3. Deixe o modelo escolher um intervalo suspeito a partir dos timecodes dos quadros ou da faixa de áudio.
  4. Execute o Squish novamente com --start / --end, depois verifique a resposta contra o clipe de origem.

O índice propõe; a evidência visual ampliada confirma. A faixa de áudio pode localizar atividade, mas não pode dizer o que foi dito ou o que fez o som.

OpenAI Build Week 2026

A extensão da Build Week adicionou seleção de candidatos guiada por áudio ao loop de navegação existente do Squish. Antes do evento, o Squish já produzia folhas de contato com carimbo de tempo e suportava zoom absoluto start/end. A Build Week adicionou a faixa de atividade de áudio normalizada em todo o clipe, audio.samples[] de tempo absoluto, preservação de transientes/alta frequência, testes e o fluxo de trabalho de agente que usa o sinal para decidir onde a visão deve inspecionar em seguida.

A demonstração mantém duas camadas de prova separadas:

  • Prova narrativa: filmagens de câmera privada autorizadas pelo proprietário são mostradas com recibos, mas a filmagem de origem não é distribuída.
  • Prova reproduzível: o repositório público contém um fixture gerado e sua fonte sob examples/audio-navigation/.
git clone https://github.com/getsquish/squish.git
cd squish
./examples/audio-navigation/generate-sample.sh
npx -y @getsquish/squish@0.3.1 examples/audio-navigation/sample.mp4 --json --out /tmp/squish-overview
npx -y @getsquish/squish@0.3.1 examples/audio-navigation/sample.mp4 \
  --density 6x6 --start 11.5 --end 13.5 --json --out /tmp/squish-zoom

A faixa de atividade da visão geral propõe a vizinhança. A folha visual densa confirma o breve marcador rosa. O 0.3.1 público usa uma escala de referência em todo o clipe de origem completo; ele não torna níveis de arquivos separados globalmente comparáveis.

CLI

squish clip.mov                       # sheets land beside the input
squish clip.mov --density 5x5 --json  # denser grid + machine-readable output
squish clip.mov --start 1:00 --end 1:30 --density 5x5   # zoom into a range

Saída: <basename>.sheet-N.jpg — uma grade de quadros com carimbo de tempo com uma fina faixa de atividade de áudio acima dela. Densidade padrão 3×3 recupera o que aconteceu; 4x46x6 recuperam como foi feito. --out <dir> escolhe o destino. Vídeos sem trilha de áudio ainda funcionam e são marcados NO AUDIO TRACK.

--start / --end levam segundos (90) ou um timecode exatamente como carimbado em uma folha (1:30, 1:07.3) e limitam a execução a esse intervalo. Timecodes são sempre absolutos em relação ao vídeo de origem, então você pode aplicar zoom repetidamente: visão geral → detectar um intervalo → re-executar com --start/--end → timecodes mais finos → perfurar novamente. Janelas curtas carimbam timecodes de sub-segundo (1:07.3) para que células adjacentes permaneçam distinguíveis.

Com --json, a saída padrão é um objeto (contrato congelado — analise contract para detectar mudanças quebradas):

{
  "input": "/abs/path/clip.mov",
  "duration": 20.275,
  "frames": 9,
  "sheets": 1,
  "files": ["/abs/path/clip.sheet-1.jpg"],
  "audio": {
    "present": true,
    "normalization": "clip_peak",
    "window": { "start": 0, "end": 20.275 },
    "samples": [
      { "time": 0.106, "level": 0.08 },
      { "time": 0.317, "level": 1 }
    ]
  },
  "warnings": [],
  "contract": "squish-cli-v0"
}

O exemplo encurta audio.samples; a saída real emite um envelope de atividade uniformemente espaçado para cada folha. Os tempos de amostra são segundos absolutos da fonte. Os níveis são 0..1, normalizados para o pico em todo o clipe completo, incluindo execuções com janela, para que zooms separados permaneçam comparáveis. Saída 0 sucesso · 1 falha (mensagem no stderr). Quadros temporários são sempre limpos. Uma execução com janela adicionalmente ecoa "window": { "start": …, "end": … } (limites resolvidos, segundos) após duration — a chave está ausente quando nenhuma janela foi solicitada.

Servidor MCP

squish mcp        # stdio server

Uma ferramenta, squish_video{ video_path, density?, start?, end?, out_dir? } → o contrato CLI (incluindo audio) mais timecodes[][] (um por quadro, por folha; m:ss, m:ss.d de sub-segundo quando uma janela é curta), carimbado "contract": "squish-mcp-v0". start/end aceitam segundos ou timecodes de folha e conduzem o loop de navegação abaixo.

Funciona com Claude Code, Claude Desktop, Cursor, Hermes e qualquer cliente MCP stdio:

{
  "mcpServers": {
    "squish": { "command": "npx", "args": ["-y", "@getsquish/squish", "mcp"] }
  }
}

MCP remoto — aplicativos oficiais de IA, sem instalação

A mesma ferramenta pela rede, para clientes que só aceitam uma URL de conector: Claude Desktop / claude.ai → Configurações → Conectores → Adicionar conector personalizado → https://api.getsquish.app/mcp. O endpoint busca um video_url público (sem sistema de arquivos compartilhado), retorna links de folhas de ~24 h mais a primeira folha embutida, e start/end funcionam exatamente como a ferramenta local.

Chamadas sem chave usam uma pequena faixa anônima gratuita; uma chave de API Authorization: Bearer (mesmas chaves e créditos da API hospedada, criada em getsquish.app/api-keys) desbloqueia jobs com preço de crédito com visibilidade de cota em cada resultado. Chaves funcionam em qualquer cliente que possa enviar o cabeçalho — Claude Code, mcp-remote, clientes SDK ou um conector Claude Team/Enterprise cujo administrador da organização anexou a chave como cabeçalho de solicitação; o diálogo do conector do consumidor é somente OAuth. Referência completa: documentação do MCP remoto.

O loop de navegação

  1. Visão geral — chame squish_video (MCP) ou squish clip.mov --json (CLI) e leia a(s) folha(s) com visão. As células correm em ordem de tempo, esquerda→direita, topo→base.
  2. Navegue — detecte as regiões que importam; cada célula carrega um timecode absoluto. Trate um pico de áudio como um intervalo candidato, não uma interpretação do que fez o som.
  3. Zoom — chame novamente com start/end definidos para os timecodes que você detectou, apenas onde a incerteza permanece: folhas mais densas de uma janela mais estreita, endereços ainda absolutos.
  4. Repita até que a resposta seja observável — nunca releia o clipe inteiro em alta densidade quando apenas um intervalo importa.
  5. Cite carimbos de tempo absolutos ("em 0:07 a prensa desce").

Privacidade

O CLI e o servidor MCP local processam tudo na sua máquina — nada é enviado, nunca, e cada densidade é gratuita. Dois caminhos movem deliberadamente mídia pelo Squish: a API hospedada (um upload intencional, créditos pré-pagos, com uma cota diária gratuita para contas que nunca compraram) e o endpoint MCP remoto (o servidor busca seu video_url público; a fonte é excluída no final do job, as folhas expiram após ~24 h).

A atividade de áudio está disponível no pacote CLI/MCP local. É um envelope de energia estilo RMS, não reprodução de áudio, transcrição, diarização, reconhecimento de som ou inferência de emoção. O aplicativo web, a API hospedada e o MCP remoto permanecem somente visuais até que suas próprias notas de versão digam o contrário.


Este repositório

Este é o motor — as bocas CLI + MCP do Squish, publicado no npm como @getsquish/squish. É uma exportação curada, primeiro-espelho de um monorepo privado (que permanece a fonte da verdade); o histórico aqui começa no primeiro lançamento público. Veja CONTRIBUTING.md para saber como as mudanças fluem.

Não neste repositório, de propósito:

  • o aplicativo web getsquish.app (PWA) — mesmos planejadores principais, mãos de navegador;
  • a API hospedada (api.getsquish.app) e seu endpoint MCP remoto (/mcp, o conector de aplicativos oficiais) — o trilho pago: upload intencional / URLs buscadas pelo servidor, créditos pré-pagos, uma cota diária gratuita para contas que nunca pagaram e uma pequena faixa anônima gratuita no conector;
  • ativos de marca — o nome Squish, logotipo, mascote e imagens OG são reservados.
src/            CLI (main/args) · engine (probe → plan → extract → compose → write) · MCP server · sheet renderer
src/core/       pure planners shared with the web app: density · sampling · grid layout · timecode format
tests/          node:test suite + a real-MCP-client e2e
skills/         agent skills — `npx skills add getsquish/squish` installs video-navigation

Licença

Apache-2.0 (com NOTICE). O nome Squish, logotipo, mascote e ativos de marca getsquish.app não são licenciados por este repositório.