Communitygithub.com

eternityspring/reelbench-skills

Combina datos de análisis de tomas con el video original para generar un video directamente visible: en un lado la imagen, en el otro la información de la toma actual (número de toma, inicio/fin, duración, plano, tipo, movimiento, descripción de la imagen, diálogo). La información cambia al cambiar de toma, la tabla de tomas se desplaza automáticamente y resalta la toma actual. El diseño se adapta según la relación de aspecto del video original: horizontal/cuadrado → imagen arriba, información abajo; vertical → imagen a la izquierda, información a la derecha. La imagen siempre se escala sin recortes. La tabla se desplaza con la reproducción: en los puntos de corte se mueve para llevar la toma actual al punto de anclaje y luego se detiene, con la barra de resaltado moviéndose sincronizada. La implementación solo captura tres imágenes (base + dos imágenes largas desplegadas), el desplazamiento y resaltado se realizan mediante ffmpeg recortando ventanas por tiempo. El diseño está completamente en scripts/panel.css, modificándolo puedes cambiar el diseño sin tocar el script. Consume el shots.json generado por video-shots (usa frames/ como miniaturas si están disponibles). Sin dependencias npm, usa ffmpeg para la composición y un navegador sin cabeza para renderizar el panel. Úsalo cuando te pidan exportar video, combinar video, video con información de tomas, video anotado con tomas, etc.

¿Qué es reelbench-skills?

Este skill de agente de IA, llamado video-sync, automatiza la creación de un video compuesto que muestra el video original junto con una tabla de tomas detallada. Es ideal para directores, editores o cualquier persona que necesite una vista previa visual de la información de cada toma (número, duración, tipo de plano, descripción, diálogo) sincronizada perfectamente con la reproducción del video. El skill es extremadamente eficiente: solo captura tres imágenes del panel (una base y dos versiones de la tabla completa) y utiliza ffmpeg para manejar el desplazamiento y resaltado en tiempo real, lo que reduce drásticamente el tiempo de procesamiento. La lógica de diseño está separada en un archivo CSS (panel.css), lo que permite personalizar la apariencia sin modificar el script principal. Funciona en plataformas como Claude Code, Cursor, Codex, etc., siempre que tengan acceso a node, ffmpeg y un navegador sin cabeza como Chrome o Chromium. El skill consume el archivo shots.json generado por video-shots y puede usar las miniaturas de frames/ si están disponibles. No depende de npm, lo que lo hace portátil y fácil de implementar.

Compatible con✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/eternityspring/reelbench-skills/tree/HEAD/skills/video-sync

Preguntar en tu IA favorita

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

Documentación

video-sync

Combina shots.json + video original en un solo video: en un lado la imagen, la información de la toma actual en el otro lado, la información cambia cuando cambia la toma, la tabla de tomas se desplaza automáticamente y resalta la toma actual.

El diseño solo depende de la relación de aspecto, nada más:

Video originalDiseñoMétodo de composición
Horizontal (ancho > alto) o cuadradoImagen arriba, información abajovstack
Vertical (alto > ancho)Imagen a la izquierda, información a la derechahstack

En ambos casos, se garantiza que la imagen se escala sin recortes ni estiramientos, y el panel ocupa el espacio restante.

Solo se capturan tres imágenes, el movimiento se lo dejamos a ffmpeg. Lo único que cambia en el panel son dos cosas: la posición de desplazamiento y qué fila está resaltada. Así que medimos la altura de las filas una vez, capturamos una imagen base y dos imágenes largas desplegadas de la tabla de tomas (una oscurecida y otra completamente iluminada). El desplazamiento = recortar una ventana de la imagen larga oscurecida, el resaltado = recortar una fila de la imagen larga iluminada y superponerla, las posiciones se controlan con un sendcmd que envía una pequeña expresión en cada punto de corte. Para un video de 53 tomas, las capturas se reducen de 53 a 3 (12 segundos).

La toma actual se fija en la segunda fila: las tomas 1 y 2 no se desplazan (el resaltado se mueve una fila hacia abajo), a partir de la toma 3, cada corte desplaza una fila hacia arriba. El movimiento ocurre solo en los cortes, no dentro de la toma: en el punto de corte, el desplazamiento tarda --ease (por defecto 0.45) segundos en llegar y luego se detiene. Si la lista se moviese continuamente durante una toma larga de 16 segundos, el espectador tendría que estar mirando fijamente el movimiento durante 16 segundos.

La altura de la fila la determina el contenido: si la descripción es larga, la fila será más alta. La barra de resaltado se divide según la altura de la fila (la altura de crop no se puede cambiar durante la ejecución).

{baseDir} = directorio donde se encuentra este archivo. Script {baseDir}/scripts/video-sync.mjs, sin dependencias, se ejecuta directamente con node.

Límites (lo que no hace): No hace análisis de tomas (eso es trabajo de video-shots, este skill consume su shots.json), no edita, no añade transiciones, no pone música, no quema subtítulos en el video, no hace renderizado cuadro por cuadro (los efectos de movimiento los hace ffmpeg recortando ventanas por tiempo).


Paso 0 — Primero, tener los datos de análisis

Necesitas un archivo shots.json (salida de video-shots) y el video original correspondiente. Si tienes frames/ (un fotograma clave por toma), mejor: la tabla de tomas usará el primer fotograma como miniatura; si no, se deja un espacio en blanco.

shots.json debe coincidir con este video: si meta.durationSeconds no coincide con el video original, no combines; primero corrige el análisis.

Paso 1 — Primero ver la geometría, luego procesar el video

node {baseDir}/scripts/video-sync.mjs plan shots.json --video <video>

Solo calcula, no combina. Resultado en segundos: diseño, área de video, área de panel, tamaño de salida. Verifica que estos tres números sean correctos antes de continuar — combinar un video de 3 minutos lleva uno o dos minutos, si te equivocas y tienes que repetir, no vale la pena.

Si no te gusta, ajústalo: --panel <proporción> (en horizontal es alto del panel ÷ alto del video, por defecto 0.8; en vertical es ancho del panel ÷ ancho del video, por defecto 1.6), --width / --height (límite superior del área de video, por defecto 1920 / 1080).

Si el video original es demasiado pequeño, agranda el área de video: el panel se calcula a partir del área de video. Para un video de 640×360, el panel sería solo 640×288, con cuatro columnas apretadas ilegibles. --scale 2 agranda el área de video a 1280×720 y el panel a 1280×576, manteniendo la relación de aspecto. El valor por defecto es 1 (solo reduce, no agranda). plan / panels / compose / export deben usar el mismo --scale.

Paso 2 — Renderizar el panel

node {baseDir}/scripts/video-sync.mjs panels shots.json --video <video> \
  --frames frames --lang zh|en [--out panels] [--chrome <ruta>]

Genera static.png (base), list-dim.png / list-lit.png (imágenes largas desplegadas de toda la tabla de tomas, una oscurecida y otra iluminada), layout.json (posiciones de cada fila, para calcular el desplazamiento durante la composición), y además un archivo panels/panel.html — si lo abres en un navegador, puedes previsualizar el panel, cambia #S07 para ver el efecto de diferentes tomas (la animación de desplazamiento en la vista previa es igual que la de la exportación).

Para cambiar el diseño, modifica {baseDir}/scripts/panel.css, luego vuelve a ejecutar panels para obtener el nuevo diseño, sin tocar el script ni replantear la lógica de captura. Convenciones de estilo en {baseDir}/references/panel-style.md.

Paso 3 — Composición

node {baseDir}/scripts/video-sync.mjs compose shots.json --video <video> \
  [--panels panels] [-o out.mp4] [--crf 20] [--ease 0.45]

La pista de audio se copia directamente del video original (si es mudo, no se añade pista de audio). Al terminar, stderr mostrará el tamaño de salida, duración y diseño. Verifícalo.

También puedes hacer los dos pasos en uno:

node {baseDir}/scripts/video-sync.mjs export shots.json --video <video> -o out.mp4 --frames frames

Paso 4 — Verificar extrayendo fotogramas ⛔ No se puede saltar

No entregues solo porque la composición no dio error. Extrae al menos tres fotogramas para verificar que la información coincida con la imagen:

for t in 5 30 60; do ffmpeg -v error -y -ss $t -i out.mp4 -frames:v 1 -q:v 3 /tmp/check-$t.jpg; done

Verifica tres cosas: si este fotograma pertenece a la toma correcta, si el número de toma en el panel es el mismo, si la fila de resaltado sigue correctamente. Si no coinciden, generalmente es porque shots.json no es del mismo video, o --video apunta al video incorrecto.

Reporta en una frase clara: ruta de salida, tamaño, duración, diseño, número de tomas, qué imágenes del panel no se generaron (si las hay).


Límites

  • El desplazamiento solo ocurre en los puntos de corte: se desplaza durante --ease segundos y luego se detiene. Durante la toma, el panel está estático. Se podría hacer que la lista se moviese continuamente durante toda la toma (modificando la segmentación de motionPlan), pero en tomas largas de 16 segundos el espectador tendría que estar mirando fijamente el movimiento todo el tiempo.
  • Requiere un navegador sin cabeza (Chrome / Chromium / Edge). Es el precio de poder cambiar el diseño libremente: si usáramos drawtext de ffmpeg para el panel, habría que implementar nosotros mismos el salto de línea para chino, las miniaturas, el resaltado, y cambiar el diseño implicaría modificar el filtro.
  • El vocabulario (plano / tipo / movimiento / transición) viene incluido en este skill, no importa desde otro directorio — el skill debe poder copiarse entero. Si video-shots añade nuevos términos, también hay que añadirlos aquí; de lo contrario, se mostrarán como claves de enumeración.
  • Renderizar el panel siempre son tres capturas, independientemente del número de tomas: 53 tomas ≈ 12 segundos. La composición depende de la duración del video, 203 segundos ≈ 75 segundos.

Autocomprobación

node {baseDir}/scripts/selftest.mjs

122 aserciones, sin usar ffmpeg ni abrir navegador: geometría (horizontal/cuadrado/vertical, tamaño de lados pares, límites superior e inferior, controles deslizantes), contrato de datos de la página del panel (envío de vocabulario, roles de ritmo, si hay miniatura o no, escapado), comandos de animación (cada uno debe ser corto — si la expresión es demasiado larga, ffmpeg falla directamente al configurarla), parámetros de ffmpeg. Ejecuta esto después de modificar el script.

Individual skills in this repo

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

eternityspring/reelbench-skills

把一条视频重建成「只有画面和声音」的干净文件——**源片的元数据一概不搬**: GPS、设备型号、账号 ID、创建时间、章节、GoPro 的遥测轨,全部留在原地。 走的是白名单而不是黑名单:不列要删什么,只说带什么过去(画面一条流、声音一条流), 隐私保证来自结构,不来自枚举。 难点不在容器 tag,在**看不见的那几层**:x264 把完整编码参数写成 SEI 塞在码流里、 AAC 把版本号写进 DSE、avc1 的 compressorname 里还有一份——`ffprobe` 一个都看不见。 五个藏身处逐一堵死,每一处都有实测。 默认 `--mode copy`:**画面逐字节照搬**(cmp 验证过),只重编音频,53 秒的片子 1.3 秒跑完; `--mode encode` 完整重编码,多杀掉码流域的东西。 验收不靠声称:把源片所有元数据字符串当「针」,在输出文件里做**字节级扫描**, 扎到一根就红。12 道门全部由脚本确定性检查。 零依赖、零 API key,只要 node 和 ffmpeg。 Use when asked to 清元数据、去元数据、抹掉视频信息、视频隐私、去水印信息、 strip video metadata、remove exif from video、scrub video。

eternityspring/reelbench-skills

拉片:把一条成片拆成逐镜头的分析表——每个镜头的时长、景别、类别、运镜、画面。 分工刻在骨子里:**能量的都由代码量**(切点来自 ffmpeg 场景检测,时长是切点相减, 运动量是逐帧差分的中位数),模型只判断它真正该判断的那几件事(景别 / 类别 / 运镜 / 画面 / 节奏), 然后每一条判断都被代码当场对账——**声称推拉摇移却实测几乎不动,门直接拦**。 看片走联系表(每镜起手帧 + 收尾帧各拼一张大图,一屏二十几个镜头,a/b 对照就是运镜), 不是一张张翻。检测漏刀多刀用 recut 补刀并刀,自动重编号重算时长,手改边界过不了门。 产出 shots.json + Markdown 镜头表 + **单页交互式拉片报告**:内嵌播放器(播放时同步高亮镜头、 点镜头跳转)、镜头节奏带、可搜索可筛选可排序的镜头表(列表 / 卡片两种视图、首尾关键帧并排、 点图开大图)、景别类别运镜分布、出场人物、质量门、导出 JSON。单文件零依赖,离线双击能开。 15 道质量门全部由脚本确定性检查。 零依赖、零 API key,只要 node 和 ffmpeg。 Use when asked to 拉片、拆镜头、分析视频镜头、镜头时长、景别、运镜、镜头表、 video shot breakdown、shot list from video。

Skills relacionados