Mapping - Los clips salian del reves: mapper.js activaba UNPACK_FLIP_Y_WEBGL, pero el modelo va con origen arriba-izquierda y texImage2D ya sube la primera fila en t=0, asi que el flip la mandaba al final. Comprobado renderizando el mapper real en Chromium headless con una fuente mitad roja / mitad azul. - projectM se puede usar YA en una capa: los .milk de data/presets-projectm se traducen a Butterchurn en el navegador al elegirlos (milkdrop-preset- converter). La capa MilkDrop gana 'biblioteca' (butter | projectm) sin cambiar su firma, para no recrear el contexto WebGL al cambiar de una a otra. Medido: 100/100 presets de una muestra convierten, 84/84 de los que llevan shaders warp/comp; ~7 ms por preset. - Cada capa tiene su pestana arriba y su propia vista, y '+ CAPA' crea una y entra en ella: con varias capas, ir y volver a MAPPING no era viable. - Dos capas MilkDrop sin preset ya no salen identicas (cogian el indice 0): cada instancia elige uno al azar y lo escribe en el estado. - Una capa nueva ya no nace en la fuente "motor", que es el lienzo del motor activo y hacia que dos capas ensenaran lo mismo. Galeria de visuales - scripts/catalogar-visuales.py: ficha de cada clip (pelicula, personajes, duracion) y, sobre todo, si es una silueta de verdad y cuanta figura tiene. Distingue silueta de corte crudo por el negro puro del fondo: 0,63-0,90 frente a 0,04-0,06, sin zona gris. - El panel lista los clips agrupados por pelicula, con nombre legible y aviso de los que casi no tienen figura, en vez del nombre del archivo. - Soporte de siluetas con canal alfa (.webm VP9): transparencia de verdad, sin recorte por luminancia. El shader del mapper ya la respeta. Documentacion - docs/visuales.md nuevo; pendiente.md al dia con lo hecho y lo que queda. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
6.9 KiB
La galería de visuales
Los clips que se ven en el Mezclador y en las capas del mapping viven en
data/videos. Además del archivo suelto, hay un catálogo
(data/visuales.json) con la ficha de cada uno: de qué película sale, quién
aparece, cuánto dura y — lo importante — si es una silueta de verdad y cómo
de llena está.
Sin esa ficha el panel solo puede enseñar p3-davy-jones-tormenta_silueta-negro.mp4.
Con ella enseña Davy Jones (en la tormenta), agrupado bajo Piratas del
Caribe: En el fin del mundo, y marca los que casi no tienen figura.
Cómo se genera
cd ~/COFRE/CODERS/MUSIKA/VISUALES/FOSFENO
python3 scripts/catalogar-visuales.py # cataloga y escribe el JSON
python3 scripts/catalogar-visuales.py --limpiar # + aparta los que no son siluetas
Necesita ffmpeg/ffprobe y numpy. Tarda unos segundos por clip: decodifica
2 fotogramas por segundo a 160x90 en gris y saca las cuentas de ahí.
Hay que volver a pasarlo cada vez que entran clips nuevos en la galería. El panel lo recarga solo al pulsar el botón de recargar del Mezclador, o al subir un archivo; si el JSON no está, el panel sigue funcionando con los nombres de archivo pelados.
Qué mide, y por qué así
¿Es una silueta o es un trozo de película tal cual? En un clip siluetado por DETEKTION el fondo es negro puro (valor 0), cosa que no pasa nunca en una imagen de cine, por oscura que sea. Así que basta con medir qué porcentaje del cuadro está a cero:
| negro puro | |
|---|---|
| Clips siluetados de la galería | 0,63 – 0,90 |
| Cortes sin siluetear | 0,04 – 0,06 |
No hay zona gris, y por eso el umbral está en 0,30. No es un número inventado: sale de medir la galería entera.
¿Tiene figura suficiente? Un clip puede estar perfectamente siluetado y aun así no servir, porque la escena era muy oscura y el recorte salió casi vacío. Se mide el porcentaje del cuadro por encima de gris 32, y se mira la mediana (no un fotograma suelto: casi todos los clips tienen tramos vacíos y tramos llenos, y juzgar por el fotograma central engaña).
| calidad | criterio | qué significa |
|---|---|---|
buena |
mediana ≥ 0,03 | se ve bien sobre el fondo |
floja |
mediana < 0,03 | figura pequeña o muy oscura |
vacia |
mediana < 0,005 o más de la mitad de fotogramas vacíos | apenas hay nada |
descartable |
negro puro < 0,30 | no es una silueta: se ve el fondo |
Qué hace --limpiar
Los descartable (los que enseñan el fondo entero de la película) se mueven
a data/videos/_descartados/. No se borran: si un día quieres volver a pasarlos
por DETEKTION, siguen ahí. El servidor no los sirve, porque solo lista archivos
sueltos de data/videos, no subcarpetas.
Los floja y vacia no se tocan: son siluetas correctas, solo que oscuras.
Se quedan en la galería marcadas, y ya decides tú si las usas — sobre un fondo
de MilkDrop brillante, una silueta tenue puede funcionar.
La ficha
{
"archivo": "p3-davy-jones-tormenta_silueta-negro.mp4",
"obra": "Piratas del Caribe: En el fin del mundo",
"anio": 2007,
"titulo": "Davy Jones (en la tormenta)",
"tipo": "silueta",
"modo": "silueta sobre negro",
"origen": "detektion",
"personajes": ["Davy Jones"],
"etiquetas": ["en la tormenta"],
"ancho": 1152, "alto": 480, "fps": 23.98, "duracion": 30.03,
"metricas": { "negroPuro": 0.737, "figura": 0.0582,
"figuraPico": 0.1974, "brillo": 8.49, "vacios": 0.03 },
"clase": "silueta", "calidad": "buena", "aviso": "",
"miniatura": "miniaturas/p3-davy-jones-tormenta_silueta-negro.jpg"
}
La miniatura no es un fotograma cualquiera: es el fotograma con más figura de todo el clip, que es el que dice de verdad qué vas a ver.
De dónde salen los nombres
El catálogo lee las dos convenciones de DETEKTION:
siluetear.py→<algo>_silueta-<modo>.mp4→tipo: siluetarecortar.py→<peli>_13m26s.mp4→tipo: corte(crudo, sin siluetear)
y del resto del nombre saca la película (p1…p5, hackers, tron…), los
personajes conocidos y las palabras de escena. Las tablas están arriba del
todo en scripts/catalogar-visuales.py: para añadir películas o personajes
nuevos se tocan ahí y ya.
Un clip que no encaje en ninguna tabla no rompe nada: sale con el nombre prettificado y agrupado en "Sin catalogar".
Transparencia de verdad (canal alfa)
Hay dos formas de que un personaje se vea sobre las visuales, y conviene no confundirlas:
1. Recorte por luminancia (lo de siempre). El clip _silueta-negro.mp4
tiene fondo negro opaco, y es el Mezclador el que lo hace transparente al
vuelo: src(s0).layer(src(s1).luma(umbral, 0.15)). Funciona y va en H.264,
que es lo que mejor decodifica una Raspberry. Pega: hay un umbral que ajustar,
y las zonas oscuras del propio personaje (pelo, ropa negra) se comen con él.
2. Canal alfa de verdad (_silueta-alfa.webm). El clip lleva la
transparencia dentro, en un WebM con VP9. No hay umbral, no hay bordes
comidos: los píxeles del fondo simplemente no existen, y debajo se ve la
capa que haya. Se genera con:
.venv/bin/python3 siluetear.py clip.mp4 --modo alfa
FOSFENO ya lo compone bien sin tocar nada: el fragment shader del mapper
saca gl_FragColor = vec4(c.rgb, c.a * uAlpha) y mezcla con
SRC_ALPHA / ONE_MINUS_SRC_ALPHA, así que una capa con alfa deja ver la capa
dibujada antes que ella. Comprobado, no supuesto: con una capa de fondo
roja y encima un clip alfa, el 48,6 % de la pantalla sale roja por los huecos.
Para que se vea a través hace falta que haya algo debajo: otra capa del mapping dibujada antes (MilkDrop, shader, cámara). Si el clip alfa es la única capa, debajo solo está el negro del compositor.
Dos trampas del alfa en WebM
- El decodificador VP9 nativo de ffmpeg se come el alfa en silencio: no
falla, devuelve el vídeo entero opaco. Para leerlo hay que pedir
-c:v libvpx-vp9a mano. Es exactamente por esto que el catalogador mide estos clips conffmpeg -c:v libvpx-vp9 ... -vf format=rgba,alphaextract(y elformat=rgbano es adorno: sin élalphaextractno negocia formato y ffmpeg aborta). - VP9 no tiene decodificación por hardware en la Raspberry Pi 5, que sí la tiene para H.264/HEVC. En el portátil va sobrado; en la Pi, con clips de 480p cortos debería ir, pero hay que probarlo antes de un bolo. Si se atraganta, el camino 1 (negro + luma key) sigue ahí.
En el panel
server.py carga el catálogo en state.meta.visuales ({archivo: ficha}),
filtrado contra lo que hay de verdad en disco para que un catálogo viejo no
enseñe clips borrados. El panel lo usa en fillClipSelect(): las listas de
clips salen agrupadas por película con <optgroup>, con el título legible, la
duración y la marca de calidad (· poca figura, · casi vacio), y el aviso
completo en el title de cada opción.