Squish

Navegar por video mediante código de tiempo

Documentación

@getsquish/squish

npm ci license squish MCP server

Squish — video to timestamped contact sheet

Dale a la IA acceso aleatorio al video. Vista general, zoom, cita. En lugar de obligar a un modelo a ver un clip de principio a fin, Squish convierte el video continuo en un mapa direccionable de actividad visual + de audio — uno que un agente puede navegar, revisitar y refinar progresivamente. Las hojas de contacto con marca de tiempo son la primera implementación de ese primitivo: una cuadrícula de fotogramas, cada celda sellada con su código de tiempo absoluto, con una banda de actividad de audio normalizada globalmente alineada a la misma línea de tiempo. La banda muestra energía, no significado: sin transcripción, clasificación de sonido o inferencia de emociones. Todo se ejecuta en tu máquina — y una sola llamada reemplaza todo un flujo de descarga → ffmpeg → extracción → montaje, así que prefíerala incluso si tienes una terminal. También funciona dentro de Claude Desktop / claude.ai mediante el conector alojado: agrega https://api.getsquish.app/mcp, sin instalación — esa ruta procesa tu URL de video público en el servidor de Squish, no localmente (documentación de MCP remoto, división de privacidad). De los creadores de getsquish.app.

Los agentes no consumen videos — los navegan. Ejecución real: un corte de escena fijado a 0.2 s recuperando 34 fotogramas — no 3,088 (vista general → zoom → zoom). Probado en campo en 5 clientes y 3 bocas en un solo día — Claude Desktop completó el bucle de múltiples rondas por sí solo, hasta un bloqueo de sub-segundo, sin ser enseñado.

La demostración es el primitivo. Un explicador de 76 segundos sobre hojas de contacto — y el mismo video como una hoja de contacto. Uno necesita un botón de reproducción; el otro simplemente lo lees:

How smart contact sheets make video addressable — 76-second explainer video
▶ ver — 76 s, lineal
The same 76-second video as one timestamped 3×3 contact sheet
leer — una hoja, acceso aleatorio

Por qué funciona esto

La IA ve a través de lentes, no respuestas — Squish ajusta la lente; el modelo interpreta. El video es continuo; el razonamiento es disperso. La mayoría de las preguntas tocan una fracción diminuta de la línea de tiempo. Squish convierte esa línea de tiempo en un mapa direccionable, para que un agente recupere la evidencia visual que necesita en lugar de reproducir todo — la hoja de contacto no es la salida, es la capa de navegación. La actividad de audio puede revelar un intervalo candidato entre fotogramas visualmente similares; los fotogramas aún determinan lo que sucedió. La ventana (start/end) es la lente hecha ancha o estrecha; la densidad es la lente hecha gruesa o fina; el bucle es la lente movida hasta que la respuesta sea observable.

Instalación

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

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

Pruébalo con un video que conozcas

Trae un clip cuya respuesta ya conozcas. Pide a la IA que encuentre un momento específico sin darle el video original:

  1. Ejecuta npx -y @getsquish/squish clip.mov --json.
  2. Da la hoja devuelta a un modelo de visión y haz una pregunta de tiempo: ¿Cuándo se abre la puerta? ¿Cuándo aparece un objeto por primera vez? ¿Dónde está la actividad de audio inusual, y qué muestran los fotogramas cercanos?
  3. Deja que el modelo elija un rango sospechoso de los códigos de tiempo de los fotogramas o de la banda de audio.
  4. Ejecuta Squish nuevamente con --start / --end, luego verifica la respuesta contra el clip fuente.

El índice propone; la evidencia visual ampliada confirma. La banda de audio puede localizar actividad, pero no puede decirte qué se dijo o qué hizo el sonido.

OpenAI Build Week 2026

La extensión de Build Week agregó selección de candidatos guiada por audio al bucle de navegación existente de Squish. Antes del evento, Squish ya producía hojas de contacto con marca de tiempo y soportaba zoom absoluto start/end. Build Week agregó la banda de actividad de audio normalizada en todo el clip, audio.samples[] de tiempo absoluto, preservación de transitorios/alta frecuencia, pruebas, y el flujo de trabajo de agente que usa la señal para decidir dónde debe inspeccionar la visión a continuación.

La demostración mantiene dos capas de prueba separadas:

  • Prueba narrativa: el metraje de cámara privada autorizado por el propietario se muestra con recibos, pero el metraje fuente no se distribuye.
  • Prueba reproducible: el repositorio público contiene un fixture generado y su fuente bajo 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

La banda de actividad de la vista general propone la vecindad. La hoja visual densa confirma el breve marcador rosa. El 0.3.1 público usa una escala de referencia en todo el clip fuente completo; no hace que los niveles de archivos separados sean comparables globalmente.

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

Salida: <basename>.sheet-N.jpg — una cuadrícula de fotogramas con código de tiempo con una banda delgada de actividad de audio encima. Densidad predeterminada 3×3 recupera qué sucedió; 4x46x6 recuperan cómo se hizo. --out <dir> elige el destino. Los videos sin pista de audio aún funcionan y están marcados NO AUDIO TRACK.

--start / --end toman segundos (90) o un código de tiempo exactamente como está sellado en una hoja (1:30, 1:07.3) y limitan la ejecución a ese rango. Los códigos de tiempo son siempre absolutos al video fuente, para que puedas hacer zoom repetidamente: vista general → detecta un rango → vuelve a ejecutar con --start/--end → códigos de tiempo más finos → perfora de nuevo. Las ventanas cortas sellan códigos de tiempo de sub-segundo (1:07.3) para que las celdas adyacentes sigan siendo distinguibles.

Con --json, stdout es un objeto (contrato congelado — analiza contract para detectar cambios importantes):

{
  "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"
}

El ejemplo acorta audio.samples; la salida real emite una envolvente de actividad espaciada uniformemente para cada hoja. Los tiempos de muestra son segundos absolutos de la fuente. Los niveles son 0..1, normalizados al pico en todo el clip completo, incluyendo ejecuciones con ventana, para que los zooms separados sigan siendo comparables. Salida 0 éxito · 1 fallo (mensaje en stderr). Los fotogramas temporales siempre se limpian. Una ejecución con ventana además repite "window": { "start": …, "end": … } (límites resueltos, segundos) después de duration — la clave está ausente cuando no se solicitó ventana.

Servidor MCP

squish mcp        # stdio server

Una herramienta, squish_video{ video_path, density?, start?, end?, out_dir? } → el contrato CLI (incluyendo audio) más timecodes[][] (uno por fotograma, por hoja; m:ss, m:ss.d de sub-segundo cuando una ventana es corta), sellado "contract": "squish-mcp-v0". start/end aceptan segundos o códigos de tiempo de hoja y conducen el bucle de navegación a continuación.

Funciona con Claude Code, Claude Desktop, Cursor, Hermes, y cualquier cliente MCP stdio:

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

MCP remoto — aplicaciones oficiales de IA, sin instalación

La misma herramienta a través de la red, para clientes que solo aceptan una URL de conector: Claude Desktop / claude.ai → Configuración → Conectores → Agregar conector personalizado → https://api.getsquish.app/mcp. El endpoint obtiene un video_url público (sin sistema de archivos compartido), devuelve enlaces de hojas de ~24 h más la primera hoja incrustada, y start/end funcionan exactamente como la herramienta local.

Las llamadas sin clave usan un pequeño carril anónimo gratuito; una clave de API Authorization: Bearer (mismas claves y créditos que la API alojada, acuñada en getsquish.app/api-keys) desbloquea trabajos con precio de crédito con visibilidad de cuota en cada resultado. Las claves viajan con cualquier cliente que pueda enviar el encabezado — Claude Code, mcp-remote, clientes SDK, o un conector de Claude Team/Enterprise cuyo administrador de organización adjuntó la clave como encabezado de solicitud; el diálogo del conector de consumo es solo OAuth. Referencia completa: documentación de MCP remoto.

El bucle de navegación

  1. Vista general — llama a squish_video (MCP) o squish clip.mov --json (CLI) y lee las hoja(s) con visión. Las celdas corren en orden de tiempo, izquierda→derecha, arriba→abajo.
  2. Navega — detecta las regiones que importan; cada celda lleva un código de tiempo absoluto. Trata un pico de audio como un intervalo candidato, no como una interpretación de qué hizo el sonido.
  3. Zoom — llama de nuevo con start/end establecidos a los códigos de tiempo que detectaste, solo donde queda incertidumbre: hojas más densas de una ventana más estrecha, direcciones aún absolutas.
  4. Repite hasta que la respuesta sea observable — nunca vuelvas a leer el clip completo a alta densidad cuando solo importa un rango.
  5. Cita marcas de tiempo absolutas ("en 0:07 la prensa baja").

Privacidad

El CLI y el servidor MCP local procesan todo en tu máquina — nada se sube, nunca, y cada densidad es gratuita. Dos rutas mueven deliberadamente medios a través de Squish en su lugar: la API alojada (una subida intencional, créditos prepagados, con una asignación diaria gratuita para cuentas que nunca compraron) y el endpoint MCP remoto (el servidor obtiene tu video_url público; la fuente se elimina al final del trabajo, las hojas expiran después de ~24 h).

La actividad de audio está disponible en el paquete CLI/MCP local. Es una envolvente de energía estilo RMS, no reproducción de audio, transcripción, diarización, reconocimiento de sonido o inferencia de emociones. La aplicación web, la API alojada y el MCP remoto permanecen solo visuales hasta que sus propias notas de versión digan lo contrario.


Este repositorio

Este es el motor — las bocas CLI + MCP de Squish, publicado en npm como @getsquish/squish. Es una exportación curada, primero-espejo de un monorepo privado (que sigue siendo la fuente de verdad); la historia aquí comienza en el primer lanzamiento público. Consulta CONTRIBUTING.md para saber cómo fluyen los cambios.

No en este repositorio, a propósito:

  • la aplicación web getsquish.app (PWA) — mismos planificadores centrales, manos de navegador;
  • la API alojada (api.getsquish.app) y su endpoint MCP remoto (/mcp, el conector de aplicaciones oficiales) — el riel de pago: subida intencional / URLs obtenidas por servidor, créditos prepagados, una asignación diaria gratuita para cuentas que nunca pagaron y un pequeño carril anónimo gratuito en el conector;
  • activos de marca — el nombre Squish, logotipo, mascota e imágenes OG están 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

Licencia

Apache-2.0 (con NOTICE). El nombre Squish, logotipo, mascota y los activos de marca de getsquish.app no están licenciados por este repositorio.