CommunityProgramación y desarrollogithub.com

businessbaum/vedit

Este skill se usa cuando el usuario solicita un gráfico en pantalla, título o superposición: "bau eine Bauchbinde", "mach ein Lower Third", "blend meinen Namen ein", "mach eine Titelkarte", "setz einen Text drüber", "brauch eine Grafik dazu", "zeig da eine Zahl an", "mach ein Intro-Insert", "build a lower third", "add a title card", "put a graphic over this", "overlay some text", "animate this number". Abarca el contrato de plantillas HTML, el renderizado de frames con Chrome headless, la codificación de películas con preservación alfa y el bloque de superposiciones en project.json.

¿Qué es vedit?

Este skill permite crear gráficos en pantalla, títulos y superposiciones (lower thirds, tarjetas de título, intros, etc.) renderizando páginas HTML frame a frame con Chrome headless y codificándolas en una película con canal alfa. Está diseñado para flujos de trabajo de producción de video donde la precisión, determinismo y rendimiento son críticos. El skill se basa en un principio fundamental: cada gráfico debe ser una función pura del tiempo (`?t=<segundos>`), sin animaciones CSS ni `requestAnimationFrame`, lo que garantiza que el renderizado sea determinista y cacheadle. Soporta la escritura de plantillas HTML autocontenidas, el renderizado paralelo con hasta cuatro procesos Chrome, la codificación a formatos como QuickTime RLE (qtrle) o ProRes 4444, y el anclaje de superposiciones a segmentos del timeline mediante `{segment_id, offset_frames}`. Además, incluye verificaciones automáticas de calidad: prueba de canal alfa, detección de páginas en blanco y comprobación de determinismo. Es ideal para editores, motion graphics designers y desarrolladores que integren gráficos en plataformas como Premiere, After Effects o sistemas de emisión en vivo.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/businessbaum/vedit/tree/HEAD/.agents/skills/gfx-html

Installed? Explore more Programación y desarrollo skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

gfx-html

Los gráficos son páginas HTML renderizadas frame a frame por Chrome headless y codificadas en una película con canal alfa. El texto completo de la solicitud está en $ARGUMENTS; el primer token suele ser el slug del proyecto. Los nombres de los verbos siguen el contrato de compilación; python engine/ve.py --help resuelve conflictos.

La regla que hace funcionar este carril

Cada gráfico es una función pura de ?t=<segundos>. Sin animaciones CSS, sin líneas de tiempo GSAP, sin requestAnimationFrame, sin transiciones. La página lee t de location.search, calcula su diseño y renderiza un frame estático.

Esto no es una preferencia de estilo. chrome --headless --screenshot se ejecuta "cuando la página parece cargada" - no hay un reloj virtual en esta compilación, no hay Emulation.setVirtualTimePolicy, no hay beginFrame. Una página con animaciones CSS muestreada de esa manera devuelve píxeles diferentes en cada ejecución. Eso destruye el almacenamiento en caché direccionado por contenido (misma clave, píxeles diferentes) y produce un parpadeo visible.

Una función pura de t muestreada por el mismo bucle ingenuo es determinista y cacheadle, y esa es toda la diferencia.

El presupuesto, expresado de antemano

Chrome renderiza a ~430-470 ms por frame en estado estable, con un arranque en frío de 7.9 s. Un gráfico de 5 segundos a 30 fps son 150 frames, aproximadamente 65 segundos en un solo hilo. El motor paraleliza cuatro procesos Chrome y almacena en caché los PNG por frame, por lo que un gráfico sin cambios se vuelve a renderizar gratis - pero un primer renderizado no es instantáneo.

Informa al usuario el número de frames y la estimación antes de comenzar uno largo. Prefiere gráficos cortos: un lower third que se mantiene durante 6 segundos no necesita 6 segundos de movimiento, necesita 0.4 s de entrada, una pausa y 0.4 s de salida.

Paso 1 - Elegir o escribir una plantilla

Las plantillas viven en presets/graphics/*.html. Reutiliza antes de escribir. Una plantilla es un único archivo HTML autocontenido que:

  • Lee t (segundos) y sus propiedades de location.search.
  • Calcula todas las posiciones/opacidades a partir de t con aritmética simple. Las funciones de easing están bien, son puras.
  • Renderiza sobre un cuerpo transparente. Nunca pintes un color de fondo.
  • Utiliza fuentes de assets/fonts/ mediante @font-face con una URL file:///. No confíes en las fuentes del sistema: lo que Chrome resuelva en esta máquina no es lo que asume el renderizado de control de QC.
  • Es legible a 1920x1080 y dentro del área segura de subtítulos de la plataforma. Verifica output.platform: un lower third que se sitúa en el tercio inferior está debajo de la interfaz de TikTok.

Los detalles de diseño, las convenciones de easing y el contrato de propiedades están en docs/graphics.md. No los repitas aquí.

Paso 2 - Renderizar frames

python engine/ve.py gfx <slug>

Por frame, el motor invoca Chrome como una lista de argumentos, aproximadamente:

chrome.exe --headless=new --disable-gpu --no-sandbox --hide-scrollbars
           --user-data-dir=<win-path>\prof --default-background-color=00000000
           --window-size=1920,1080 --screenshot=<win-path>\frame_0007.png
           "file:///C:/.../template.html?t=0.233&title=..."

Dos banderas sostienen todo el carril:

  • --default-background-color=00000000 produce el verdadero alfa. Verificado: el píxel de la esquina lee 0 0 0 0. Sin él obtienes negro opaco y la superposición cubre el video.
  • La URL file:/// debe ser una ruta real de Windows. Una ruta $PWD de Git Bash falla silenciosamente - tres archivos HTML diferentes produjeron el mismo md5 de una página de error en modo oscuro en blanco, salida 0, tamaño de archivo plausible. Por eso la verificación de QC (g) compara con el hash de página en blanco conocido.

Los frames se almacenan en caché bajo .cache/html/ con clave sha256(contenido_html + t + params + renderer + version_renderer). Cambiar la plantilla invalida cada frame, lo cual es correcto.

Paso 3 - Codificar con alfa intacto

Mismo comando. ve gfx renderiza los frames y los codifica en un solo paso - no hay un verbo de codificación separado, porque una secuencia de PNG sin película al lado es un artefacto a medio terminar que nada aguas abajo puede usar.

Secuencia de PNG a QuickTime RLE (qtrle, argb). ProRes 4444 y una secuencia de PNG sin procesar también conservan el alfa correctamente. VP9 en WebM descarta silenciosamente el alfa en esta compilación, incluso con -metadata alpha_mode=1 - no lo uses, y no lo aceptes de un activo de usuario sin verificar.

La salida va a .cache/ovl/<xx>/<key>.mov con un archivo lateral <key>.json.

Paso 4 - Anclar la superposición

Escribe la entrada overlays[]: id, kind: "html", template, props, anchor, duration_frames, layer, render.

anchor siempre es {segment_id, offset_frames} - nunca una posición absoluta en la línea de tiempo. Las posiciones en la línea de tiempo se derivan de una suma acumulativa sobre los segmentos habilitados. En el momento en que alguien deshabilita un segmento aguas arriba, cada posición absoluta es incorrecta y cada gráfico se desplaza. Una superposición anclada se mueve automáticamente con su segmento, que es el comportamiento que espera un editor.

layer ordena la composición; los valores más altos están encima. Los subtítulos se renderizan al final y se sitúan sobre los gráficos.

Paso 5 - Verificar antes de declarar terminado

Tres verificaciones, todas económicas:

  1. Prueba alfa. Lee un píxel rgba sin procesar de un frame de esquina y verifica que a = 0. QC (d).
  2. Verificación de página en blanco. Verifica que los frames no sean todos de un color sólido. QC (g). Esto detecta una URL file:/// incorrecta, una fuente que no se cargó y un error de JavaScript, todos los cuales de otro modo salen con 0 y un archivo de tamaño plausible. Toma muestras del primer frame, del medio y de los tres cuartos, y falla solo si todos son uniformes - cada plantilla aquí se abre con opacidad 0, por lo que el frame 0 de un gráfico funcional es legítimamente blanco y juzgar solo con él falla un renderizado correcto.

ve gfx ejecuta ambas automáticamente sobre lo que acaba de crear y sale con código 2 si alguna falla. 3. Determinismo. Renderiza un frame dos veces y compara los hashes. Si difieren, algo en la plantilla no es una función pura de t - encuéntralo. Esta verificación existe porque el error que detecta es invisible hasta que un renderizado en caché discrepa de uno nuevo.

Luego muestra al usuario un fotograma fijo en el punto medio. No describas un gráfico en prosa cuando una captura de pantalla está a un comando de distancia.

Modos de fallo

SíntomaCausaSolución
La superposición cubre el video con negroFalta --default-background-color, o la plantilla pinta un fondoAgrega la bandera; haz el cuerpo transparente
Cada frame idéntico, tamaño de archivo plausiblePágina de error en blanco por una URL file:/// incorrectaUsa una ruta real de Windows; verifica contra el hash de página en blanco
Misma clave, píxeles diferentes entre ejecucionesLa plantilla no es una función pura de tElimina toda animación CSS y rAF
El texto se renderiza con la tipografía incorrectaRetroceso a fuente del sistema@font-face desde assets/fonts/ con una URL file:///
Alfa perdido después de la codificaciónVP9/WebMUsa qtrle argb o ProRes 4444
El gráfico se desplaza después de una edición aguas arribaAnclaje absoluto en la línea de tiempoAncla a {segment_id, offset_frames}
El renderizado toma minutos430 ms/frame es el mínimoAcorta el gráfico o acéptalo; el caché hace que la segunda ejecución sea gratuita

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

businessbaum/vedit

This skill should be used when the user asks for subtitles or on-screen text of what is being said - "brenn die Untertitel ein", "mach Untertitel", "Untertitel drauf", "leg Untertitel drüber", "brenn die Subs ein", "mach die Captions", "Wort für Wort Untertitel", "Karaoke-Untertitel", "korrigier den Untertitel-Text", "burn in the captions", "add subtitles", "burn the subs", "word-by-word captions", "fix a caption typo". Covers ASS generation, the pixel-width grouping rule for German, the font table, and burn-in through libass.

businessbaum/vedit

This skill should be used when the user asks for mechanical tightening of material that is already selected - "mach den Rohschnitt", "bau den Rohschnitt", "schneid die Ähms raus", "nimm die Füllwörter raus", "entferne die Pausen", "kürz die Pausen", "schneid die Versprecher raus", "mach den Radioschnitt", "straff das", "build the rough cut", "cut the fillers", "remove the ums", "tighten the pauses", "trim the dead air", "cut the retakes", "radio edit". Turns kept story blocks into enabled segments in project.json. Does not decide what the video is about - that is cut-story.

businessbaum/vedit

This skill should be used when the user asks to decide what the video is actually about before any mechanical cutting - "bau die Story", "was soll ins Video", "was kann raus", "welche Themen bleiben", "kürz das auf 6 Minuten", "mach daraus ein kurzes Video", "wo ist der Hook", "sortier die Themen", "worum geht es hier eigentlich", "build the story", "decide what stays", "structure this", "cut this down to N minutes", "find the hook", "reorder the topics". This is the CONTENT-selection pass that writes the "story" block in project.json; it runs after transcribe and before cut-rough.

businessbaum/vedit

This skill should be used when the user asks for the finished video file - "exportier das", "render das fertig", "mach das final", "renderte das Video", "mach den Endexport", "bau das Video zusammen", "mach es fertig für YouTube", "gib mir die MP4", "export the final", "render the final cut", "make the master", "export for TikTok", "give me the mp4". Covers segment rendering with the cache, guarded concat, the one-pass audio, loudness normalisation and the single mux.

Skills relacionados