Bucles sin costuras en código, con tu sujeto de Scenario MCP
Resumen
Un bucle aquí es una función pura del tiempo. draw(ctx, w, h, t, P) pinta el fotograma en el segundo t, y cada movimiento en él se repite con un periodo que divide la duración del bucle (12 s), por lo que el fotograma en 12 s es el fotograma en 0 s y el clip se repite sin costura. Nada se genera: nada se deforma o parpadea, cambiar un color lo renombra, y el mismo código renderiza a cualquier tamaño. La exploración de Bucles de Movimiento en scenario.com muestra 80 bucles hechos de esta manera (40 fondos, 40 animaciones de formas), cada uno con su código. scripts/loop-template.html contiene los mismos helpers (M.*), paleta (P) y registro tile(...) contra los que se escribieron esos bucles, por lo que su código de tile se ejecuta sin cambios.
Scenario MCP hace lo que el código no puede dibujar: el sujeto del usuario. Una mascota, producto o personaje sale de Scenario como un recorte sobre fondo transparente, y la página del bucle lo dibuja sobre el bucle en su propio reloj, por lo que obtiene el mismo desenfoque de movimiento y la composición sigue siendo un bucle. Para un sujeto que realmente se mueve, se genera una toma de video AI a partir de ese recorte, se le elimina el fondo en Scenario, y la toma se superpone sobre el bucle renderizado con ffmpeg. El bucle en sí nunca necesita un modelo y no cuesta nada de renderizar.
Necesita Node 18 o más reciente, Playwright (npm install playwright, luego npx playwright install chromium; o --channel chrome con Google Chrome instalado), ffmpeg y ffprobe. Scenario MCP solo es necesario para el sujeto. Conexión, elección de modelo y el bucle de generación: la habilidad scenario si está instalada, de lo contrario references/scenario-mcp.md.
Referencia rápida
cp scripts/loop-template.html loop.html # un bucle por archivo: configuración, draw(), superposición
# abre loop.html en un navegador: vista previa en vivo; ?t=3 lo congela, ?tone=accent o ?tone=light cambia el tono
node scripts/render-loop.mjs loop.html --check # determinismo y costura del bucle, sin video
node scripts/render-loop.mjs loop.html --stills look --at 0,3,6,9 # fotogramas fijos para revisar
node scripts/render-loop.mjs loop.html --out loop.mp4 # 12 s, 1920x1080, 24 fps
node scripts/render-loop.mjs loop.html --params "overlay=subject.png" --out loop.mp4 # con un recorte
node scripts/render-loop.mjs loop.html --width 1080 --height 1920 --out loop-9x16.mp4 # vertical
node scripts/render-loop.mjs --qa loop.mp4 composite.mp4 # verificación de costura y formato de cualquier MP4
Ejecútalo desde una carpeta donde Playwright esté instalado. Los archivos existentes nunca se sobrescriben sin --force. La verificación de página renderiza el mismo momento dos veces (debe coincidir), compara el fotograma exactamente en 12 s con el fotograma en 0 s, y compara el paso a través del punto de bucle con el movimiento a su alrededor y en los otros límites del ciclo. Un renderizado se niega a codificar a menos que imprima PASS; --ignore-seam es solo para un corte diseñado para estar en el punto de bucle.
| Regla | Por qué |
|---|---|
Cada periodo divide 12 s (1, 1.5, 2, 3, 4, 6, 12); usa M.phase(t, period, offset) | el fotograma en 12 s es igual al fotograma en 0 s |
| Los desplazamientos mueven un número entero de repeticiones del patrón por periodo | una repetición fraccionaria salta en la costura |
Aleatoriedad solo de M.rand(i, salt); no Math.random, Date ni estado entre fotogramas | el desenfoque de movimiento y las verificaciones renderizan fotogramas fuera de orden |
Tamaños desde u = h / 100, conteos desde w | correcto en 16:9, 9:16, 1:1 y en tamaño miniatura |
Colores solo de P (bg, fg, fg2, mid, accent, paper, ink), tres tonos por color de marca | renombra cambiando BRAND; contraste cambiando tono |
Eases de M.ease, con anticipación, exageración y pausas; velocidad constante solo para desplazamientos | movimiento diseñado, no mecánico |
Configuración de renderizado con la que se enviaron los 80 bucles y los valores predeterminados del script: 24 fps, 8 subfotogramas de desenfoque de movimiento sobre un obturador de 180 grados, 2x supersampling, H.264 High, CRF 16, 4:2:0, BT.709 rango limitado, faststart. Patrones que cierran el bucle, trucos de profundidad y hábitos de revisión: references/loop-craft.md.
| Paso de Scenario MCP | Llamadas |
|---|---|
| Conectar, elegir equipo y proyecto | teams_list (pregunta al usuario cuando hay varios) |
| Traer el arte propio del usuario | upload_asset, curl PUT de cada parte, upload_asset_complete |
| Elegir un modelo | recommend (txt2img, img2img, img2video, video2video), o search |
| Leer sus entradas | model_schema_get |
| Cotizar, luego ejecutar después del visto bueno del usuario | model_run con dry_run: true, luego model_run y jobs_wait |
| Obtener el resultado | asset_download, luego curl -L -o |
Ejemplo práctico: una mascota de marca flotando sobre un bucle codificado
Objetivo: un bucle sin costuras de 12 segundos a 1920x1080 en los colores de la marca con la mascota de la marca flotando en él, y opcionalmente una versión donde la mascota saluda.
-
Conectar. Llama a
teams_list. Si varios equipos o proyectos vuelven, pregunta cuál usar, y pasa suteam_idyproject_ida cada llamada posterior: con una cuenta iniciada sesión,search,model_schema_getymodel_runse niegan a ejecutarse sin ellos. -
Construir el bucle primero (local, gratuito).
cp scripts/loop-template.html mascot-loop.html, estableceBRAND.accental color de la marca y mantén el tile de ejemplo (Perspective Floor, una cuadrícula que fluye hacia la cámara) o escribe tu propiodraw(). Abre el archivo para previsualizar, luego:node scripts/render-loop.mjs mascot-loop.html --check node scripts/render-loop.mjs mascot-loop.html --stills look --at 0,3,6,9Observa los fotogramas fijos.
--checkdebe terminar enPASS. -
Traer la mascota. Si el usuario la tiene como archivo, súbela:
{ "file_name": "mascot.png", "content_type": "image/png", "kind": "image", "file_size": 482113 }(
file_sizedewc -c mascot.png.) Haz PUT de la parte a la URL devuelta con curl, luego llama aupload_asset_completecon{"upload_id": "<id de carga>"}y conserva el id del activo. -
Elegir un modelo.
recommendcon:{ "capability": "img2img", "prompt": "La mascota de la imagen de referencia, cuerpo completo, vista de tres cuartos, una pose flotante ligera, recortada sobre un fondo transparente con bordes limpios, sin sombra, sin texto", "limit": 5 }Sin un archivo, usa
"capability": "txt2img"y describe la mascota. Sinext_step.typeesask_user, muestra las opciones y espera. Prefiere un modelo cuyo esquema tenga una opción de fondo transparente; de lo contrario, planea un paso de eliminación de fondo después. -
Leer el esquema y cotizarlo.
model_schema_getcon{"model_id": "<id de recommend>"}. Construye los parámetros desde el esquema: el campo de imagen de referencia toma el id del activo subido (como un array si el esquema lo dice), y la opción de fondo transparente está establecida. Luego:{ "model_id": "<id de recommend>", "dry_run": true, "parameters": { "prompt": "<el prompt anterior>", "<campo de imagen de referencia>": ["<id del activo de la mascota>"], "<campo de fondo>": "transparent" } }Informa al usuario el precio y espera su visto bueno.
-
Ejecutar y descargar.
model_runcon los mismos parámetros y"wait": false, luegojobs_waitcon{"job_ids": ["<id del trabajo>"]}. Luegoasset_downloadcon{"asset_id": "<id del activo>", "format": "png"}ycurl -L -o subject.png "<url>"en la carpeta demascot-loop.html. Abre el PNG sobre el color de fondo del bucle al 100 %: los halos en el contorno se muestran en tonos oscuros; regenera en lugar de ocultarlos. -
Componer en el canvas y renderizar.
node scripts/render-loop.mjs mascot-loop.html --params "overlay=subject.png" --stills look --at 0,0.75,1.5,2.25 --force node scripts/render-loop.mjs mascot-loop.html --params "overlay=subject.png" --out mascot-loop.mp4 --psnr 4drawOverlay()hace flotar la mascota con un balanceo de 3 segundos y una oscilación de 6 segundos con una sombra de contacto, todos los periodos dividiendo 12, por lo que la composición sigue siendo un bucle; ajusta su tamaño y colocación allí. El script verifica la página, renderiza 288 fotogramas, codifica y verifica el punto de bucle del archivo.--psnrcompara un fotograma codificado con su renderizado sin pérdida. -
Opcional: una toma donde la mascota se mueve.
recommendcon"capability": "img2video", el id del activo del recorte como imagen de inicio y un prompt como "la mascota saluda y gira la cabeza, fondo plano liso, cámara fija, sin cortes". Esquema, cotización, ejecución,jobs_wait, descarga. Luegorecommendcon"capability": "video2video"y "elimina el fondo de este clip, mantén el sujeto con un canal alfa", eligiendo WebM VP9 con alfa como salida. Esquema, cotización, ejecución, descarga. Renderiza el bucle una vez más sin--params overlay=...(--out loop-plain.mp4) y superpone la toma sobre él con ffmpeg (el comando está en references/scenario-mcp.md). La composición tiene la duración de la toma; no es un bucle sin costuras a menos que la toma lo sea. -
Entregar el HTML (el bucle sigue siendo editable), el MP4, los fotogramas fijos y cualquier composición.
Errores comunes
- Un salto de costura en 12 s. Un periodo que no divide 12 (un ciclo de 5 s), o un desplazamiento que mueve 2.5 repeticiones.
--checkreportaSEAM JUMP(el fotograma en 12 s difiere del fotograma en 0 s). Arregla el periodo; nunca fundas los extremos. - Estado,
Math.randomoDateen un tile. El mismotda fotogramas diferentes, los subfotogramas de desenfoque de movimiento no coinciden y el bucle no puede cerrarse.--checkreportaNOT DETERMINISTIC. Calcula todo desdetyM.rand(i, salt). - Helpers de color que solo leen hexadecimal.
P.midyM.mixColordevuelven stringsrgb(), y un analizador solo hexadecimal los vuelve negros silenciosamente.M.rgbayM.mixColorde la plantilla leen ambos. - Parpadeo en movimientos rápidos. Ocho subfotogramas no son suficientes para un empuje de fotograma completo; muestra copias escalonadas. Un barrido de página completa en la construcción necesitó 40. Aumenta
--samplespara bucles muy rápidos. - Un alambre que se lee como desorden. Una malla de onda 3D lo hizo; reconstruida como líneas de cresta ocultas (cada fila llena el fondo debajo de sí misma, dibujada de lejos a cerca) se lee como terreno.
- Dividir por profundidad dos veces. Una proyección que escala la distancia focal por profundidad nuevamente encoge la escena hacia el centro. Proyecta una vez con
M.proj. - Revisar un ciclo de 3 segundos con fotogramas fijos cada 1.5 s. Eso muestra dos poses del mismo. Muestra dentro de un ciclo y en ambos lados del punto de bucle (
--at 11.9,11.95,0,0.05). - Tratar cada bandera como un error. Un chasquido diseñado (un pop, una explosión) o una pausa en el punto de bucle puede activar un detector de costura o fallo. Mira los fotogramas primero. El script compara el punto de bucle con el movimiento a su alrededor y con los otros límites del ciclo, lo que evita la mayoría de estos: los 80 bucles de la construcción lo pasan.
- Una etiqueta o contador que se envuelve mal. Cualquier cosa indexada por ciclo debe envolverse con
M.mod; en la construcción un contador de página leía "06 / 05" en el punto de bucle hasta que se hizo. - Bajo contraste en un tono. Cambia el tono (oscuro, acento, claro) para ese bucle en lugar de agregar un color.
- Un PNG de superposición desde el disco. Una página abierta desde
file://que dibuja una imagen local y lee píxeles de vuelta falla, porque la imagen contamina el canvas.render-loop.mjssirve la carpeta sobre una dirección local; la vista previa del navegador solo muestra, por lo que no se ve afectada. - Texto antes de que se cargue la fuente. El texto del Canvas no espera las fuentes web; espera
document.fonts.load(...)antes del primer fotograma, o no dibujes texto en los bucles. - Perseguir la tasa de bits. En color plano, x264 gasta muy pocos bits y el archivo se ve pequeño. En la construcción, PSNR mostró que el codificador agrega casi ninguna pérdida; la única pérdida real es la croma 4:2:0 en líneas finas saturadas. Verifica con
--psnr, y engrosa líneas finas de color en lugar de aumentar la tasa de bits. - Perder el alfa de una toma VP9. El decodificador VP9 incorporado de ffmpeg ignora el alfa; pon
-c:v libvpx-vp9antes de-i shot.webm. - Hacer el bucle con un modelo de video. El último fotograma de un clip generado rara vez coincide exactamente con el primero. Mantén el bucle como código y solo compón sobre él.