Cámara
${CLAUDE_SKILL_DIR}/cam.py: stdlib Python más ffmpeg, solo macOS. Cada imagen se recorta y
reduce de tamaño antes de que Claude la vea: una foto pegada desde el teléfono cuesta ~1600 tokens y se mantiene en el contexto,
mientras que una captura de 512 px cuesta ~260. Cada comando imprime la ruta guardada, el tamaño y el costo en tokens; Lee la
ruta solo cuando realmente necesites mirar.
Primera ejecución (nuevo usuario o nuevo Mac)
Si ~/.claude/camera-state/config.json no existe, o falla alguna captura, ejecuta:
python3 ${CLAUDE_SKILL_DIR}/cam.py setup
Esto verifica macOS, instala ffmpeg a través de Homebrew si falta, construye la aplicación auxiliar ClaudeCam,
lista las cámaras, toma un fotograma de prueba (que activa el permiso de cámara de macOS) y guarda la configuración.
Imprime READY o pasos numerados TÚ:. Transmite esos pasos al usuario en lenguaje sencillo, espera,
y vuelve a ejecutar hasta que aparezca READY. No recurras a pedir fotos sin explicar por qué.
Lo que necesita el usuario (el setup también lo explica): un iPhone XR o más nuevo con iOS 16+ con el mismo Apple ID,
Wi-Fi y Bluetooth activados, y Cámara de Continuidad habilitada; el teléfono bloqueado, quieto y en el cargador;
y hacer clic en Permitir en "ClaudeCam quisiera acceder a la cámara". La cámara del Mac funciona como
respaldo (--cam mac).
Elige el comando adecuado para cada tarea
| El usuario quiere... | Comando | Notas |
|---|---|---|
| Una mirada rápida | snap [--crop x,y,w,h] [--grid 4x3] | 512 px. Recorta al sujeto después de la primera mirada |
| Comparar estados | sheet --n 4 --every 30s | N fotogramas en mosaico en UNA imagen |
| Que le avisen cuando algo cambie | watch --every 30s --until-change | Silencioso hasta que hay un cambio; nombra la región |
| Fotos de progreso a lo largo del tiempo | timelapse --every 15m --for 6h | Mismo encuadre cada vez |
| Vigilar una impresión 3D | print locate → print use <ids> → print monitor --every 5m --for 3h | Dispara cuando el cabezal está despejado |
| Documentar montaje / construcción | step "presionar rodamiento en cubo" --project NOMBRE [--note "..."] | Foto más una entrada numerada en steps.md |
| Un vídeo de demostración del producto | clip --seconds 20 [--fps 60] [--audio] --project NOMBRE | MP4 más una hoja de fotogramas clave |
| Un vídeo a partir de fotos | compile <carpeta> [--match 'x-*.jpg'] [--fps 8] | Time-lapse, vigilancia o pasos → MP4 |
| Verificar la configuración | doctor / setup / devices |
Menú de intervalos para cualquier cosa temporizada: 5m · 10m · 15m · 30m · 45m · 60m, o cualquier 90s / 2h / 48h
(un número solo significa segundos). Ofrécelo con un valor predeterminado sensato: 5m para una impresión, 15–30m para curado,
pegamento o secado, 60m para procesos lentos que duran días.
Trabajos largos (timelapse, watch, print monitor): ejecútalos con run_in_background, como
python3 -u ... | tee <out>/run.log. Imprimen una línea por fotograma y continúan incluso si un fotograma falla.
No leas cada imagen: busca en el log failed / WARNING, mira cuando una línea parezca extraña y
revisa al final.
Proyectos. --project NOMBRE busca projects/NOMBRE/ en el directorio actual o en uno padre. Ejecutar desde
una carpeta de proyecto funciona sin la bandera. La salida va a projects/NOMBRE/media/{cam,steps,clips}/.
Sin proyecto, la salida va a ~/Pictures/claude-cam/<fecha>/, y --out DIR anula ambos. Después de una sesión de
steps o un clip de demostración, ofrece añadir una línea al registro del proyecto (si lo tiene) que
enlace al material.
Recetas para trabajo de diseño y prototipado
Flujos de trabajo de diseño industrial, diseño de producto y maker, mapeados a los comandos anteriores. Añade siempre
--project NOMBRE cuando exista una carpeta de proyecto, para que el material se guarde con el trabajo.
| Momento del proceso | Haz esto |
|---|---|
| Captura de bocetos (bocetos en papel, marcadores) | snap --cam desk --width 1600 --label sketch-<tema>. Desk View ve el papel plano sobre la mesa desde arriba. Usa una etiqueta por concepto para que las iteraciones se ordenen juntas |
| Muro de iteraciones de bocetos o modelos | compile en un conjunto --match 'sketch-*' a 1–2 fps, o sheet, para comparar variantes lado a lado |
| Iteraciones de modelos de espuma, arcilla o cartón | step "v3: mango estrechado 4 mm" --note "se sintió mejor, apoyo del pulgar demasiado bajo", un paso por iteración. El steps.md se convierte en la traza de la justificación del diseño |
| Muestras CMF (color, material, acabado) | Desk View, luz uniforme, una tarjeta blanca o gris en el encuadre; snap --width 1280 --label cmf-<nombre>. Misma iluminación cada vez, o los colores no se pueden comparar |
| Comprobaciones de ajuste y tolerancias | snap --crop ... --width 1024 con una regla o calibre en el encuadre. Escribe los números en las notas de tolerancia del proyecto, no solo en la foto |
| Ergonomía: fotos de agarre y uso | sheet --n 6 --every 3s mientras el usuario cambia de agarre: una imagen con cada postura |
| Foto de producto en plataforma giratoria | Teléfono en un soporte, el producto en un tocadiscos; sheet --n 8 --every 4s mientras el usuario lo gira 45° por sonido. Para un clip: clip --seconds 20 --fps 60 con un giro lento |
| Vídeo de mecanismo o demostración | clip --seconds 15 --fps 60 [--audio]; revisa la hoja de fotogramas clave; vuelve a grabar si el encuadre está mal. Usa el MP4 para una edición con Remotion u otra |
| Guía de montaje o construcción | step por operación en orden (--cam desk); steps.md es la guía; compile --fps 1 para una presentación |
| Pegamento, curado, secado, degradación | timelapse --every 15m --for 24h (en segundo plano); compile al final |
| Impresiones | el modo de impresión 3D a continuación |
| Prueba de usuario o sesión de co-diseño | clip --audio solo con el consentimiento explícito de los participantes, y di qué se graba y dónde se guarda. Prefiere encuadrar manos y producto sobre rostros. Mantén las grabaciones dentro de la carpeta del proyecto, nunca en lugares compartidos o públicos |
Prepara la toma primero
Antes de la primera captura real, dile al usuario de forma concreta cómo colocar el teléfono para esta tarea: qué cámara, dónde poner el teléfono, distancia, qué debe estar en el encuadre y una referencia de escala.
- Desk View (
--cam desk): el teléfono sujeto en la parte superior de la tapa del Mac, cámara trasera mirando al usuario. Esto proporciona una vista cenital de la mesa, ideal para documentaciónstepde piezas sobre la mesa. - Cámara principal (
--cam phone): cualquier soporte o trípode apuntando al sujeto. Para una impresora, colócala más arriba y más atrás a ~45°, para que el cabezal no oculte las piezas. - Luz uniforme y sin ventana en el encuadre (la deriva de autoexposición se lee como cambio). Usa la misma posición cada vez (marcas con cinta), y una regla u objeto conocido en el encuadre siempre que el tamaño importe, porque una imagen sin escala no puede dar milímetros.
- No hay zoom óptico a través de Continuity: "zoom" significa
--cropen el fotograma de 1920×1440 con un--widthmayor. El detalle real necesita el teléfono más cerca.
Luego toma una captura completa, encuentra el sujeto y mantén ese --crop para el resto de la sesión. Si un
número responde a la pregunta (una API de la impresora, una medida), salta la imagen. Para comprobaciones repetidas,
delega la mirada a un subagente ("Lee ; responde en una frase"): sus imágenes nunca
entran en el contexto principal.
Documentación y vídeo (cam_studio.py)
- step: fotos de 1280 px (calidad de documentación, ~1600 tokens si se leen; no las leas solo para
comprobarlas).
NN-slug.jpgnumerados mássteps.mdcon encabezados, imágenes y notas forman una guía de montaje lista para compartir. Usa--cam deskpara piezas sobre la mesa. Pon ajustes, problemas y tolerancias en--note. - clip: graba con H.264 (CRF 20) y AAC opcional desde el mismo micrófono del teléfono. Omite el calentamiento de ~5 s del teléfono. Modos del iPhone: 1920×1080 o 1920×1440 a 30 o 60 fps. Después, lee solo la hoja de fotogramas clave (6 fotogramas, ~600 tokens) para juzgar el encuadre y la acción. El MP4 se puede usar en una edición con Remotion u otra.
- compile: presentación de diapositivas con concat-demuxer a
--fps; los tamaños de fotograma mixtos se colocan en bandas negras (letterbox) blancas. 8 fps es adecuado para un time-lapse; 1–2 fps para una presentación de pasos.
Modo de impresión 3D (cam_print.py)
print locategraba ~40 s y construye un compuesto del percentil 25 (por píxel, el cuarto más oscuro de los momentos), de modo que la impresión aparece incluso si el cabezal la cubre más de la mitad del tiempo. La mediana NO funciona: el cabezal se detiene sobre la pieza que está imprimiendo. Encuadra candidatos oscuros sobre la cama, clasificados por lo brillante que es la cama a su alrededor. La imagen anotada de 640×480 cuesta ~410 tokens.print use 1,2,4: tú decides qué cuadros son la impresión. Letras de logotipos, correas, clips de riel y sombras de varillas pasan las pruebas de píxel, y la clasificación a veces pone las sombras de varillas primero. Si es ambiguo, toma unsnapcon cuadrícula y empareja celdas. Si nada es impresión, pide al usuario que reajuste la cámara. La selección crece con--grow(por defecto 0,15; usa 0,08 cuando las manchas de varilla tocan las piezas) para capturar piezas vecinas tenues.print shot/print monitortransmiten a 2 fps y puntúan cada fotograma por la proporción de píxeles de la impresión visibles en ese momento. Saltan fotogramas borrosos y guardan un recorte a resolución nativa. A media impresión, el cabezal puede no despejarse completamente (60–75 % visible es normal); para una placa despejada, dispara después de que termine la impresión. Asume una impresión oscura sobre una cama clara; claro sobre oscuro aún no está implementado.
Se adapta a un teléfono movido por sí solo. Cada ronda alinea sus primeros 3 s con la vista guardada. Un
golpe (error de mejor coincidencia ≤ 22) se sigue automáticamente (vista desplazada +dx,+dy px). Un
reajuste (error > 22) muestra CÁMARA MOVIDA: monitor vuelve a ejecutar locate, sale con NECESITA CONFIRMACIÓN, y
el trabajo al terminar te notifica; lee la imagen de locate, ejecuta print use y reinicia. Calibración en grabaciones:
sin mover 15,8, golpeado y realineado 15,9, escena diferente 28,9 (el cabezal en movimiento añade ~15).
Notas de fiabilidad (verificado 2026-10-15)
- El permiso de macOS va para ClaudeCam. Claude Code se ejecuta como su propio paquete auxiliar que no declara
uso de la cámara, por lo que macOS retiene silenciosamente la cámara de todo lo que genera (ffmpeg simplemente se cuelga) y
nunca la lista en Privacidad > Cámara.
cam.pylanza ffmpeg a través de~/Applications/ClaudeCam.app(construido porsetup/install-helper) conopen -W -g -n -a; macOS pregunta una vez, por ClaudeCam. - "Sin fotogramas" después de haber funcionado antes es una transmisión de Continuity atascada, no un problema de permisos.
Desbloquea el teléfono una vez, bloquéalo, déjalo quieto en el cargador y asegúrate de que ninguna otra aplicación lo esté usando.
Que
devicesaún enumere el iPhone no significa que fluyan los fotogramas. - El teléfono necesita ~5 s para conectarse y exponer (1,5 s dio negro puro sin error), por lo que salta 150 fotogramas; la cámara del Mac salta 45. Los índices de los dispositivos cambian entre llamadas, por lo que los dispositivos se eligen por nombre. El valor predeterminado de ffmpeg de 29,97 fps se rechaza, por lo que fuerza 30/60, nv12.
- Bloqueos: una ronda sin fotogramas durante 25 s se rinde y lo reintenta una vez. Un ffmpeg bloqueado ignora
SIGTERM (una vez mantuvo la cámara 9 min), por lo que
ff_stopescala a SIGKILL, y cada ronda de monitor primero ejecutapkill -9 -f cam-shot-. Mataropennunca detiene el ffmpeg dentro de ClaudeCam. - Desenfoque y congelaciones: la búsqueda de enfoque automático produjo una vez un fotograma "mejor" completamente borroso. Las tomas saltan fotogramas
por debajo del 60 % del más nítido de la ronda e imprimen
WARNING: BLURRY/WARNING: stream FROZE. - Bloqueado/dormido es necesario (Continuity solo transmite desde un teléfono bloqueado). Despertarlo después de inactividad es
más lento con batería o en Modo de bajo consumo, por lo que pide el cargador. Un teléfono movido es el verdadero riesgo:
pide al usuario que verifique la vista a través de
snap, no levantando el teléfono. open -Wsiempre sale con 0, por lo que el éxito significa que el archivo de salida existe. ffmpeg de Homebrew no tienedrawtext, por lo que las marcas de tiempo y las etiquetas de cuadrícula se imprimen como texto. Usa--input <imagen|video>para reproducir grabaciones para pruebas sin cámara (el estado va acamera-state/file/).- Figma:
upload_assetsconnodeIdssobre rectángulos de marcador de posición escalados a la relación de aspecto de la imagen funciona para colocar imágenes de cámara en un marco.