Producto propio

DJ Trainr

Subes la grabación de tu set y te digo dónde fallaste. Sin subir nada a ningún servidor.

Stack técnico

  • React 19 + TypeScript + Vite
  • Tailwind + shadcn/Radix UI
  • Web Audio API + Web Workers
  • Essentia.js (WebAssembly)
  • Análisis 100% en navegador
  • Supabase (auth + base de datos)
  • Stripe (suscripciones B2B)
  • Deploy en Vercel

El reto técnico

El reto no es la UI. Es analizar un set DJ completo (MP3, WAV, FLAC, hasta 2 GB) directamente en el navegador del usuario, sin enviarlo a ningún servidor, y sin bloquear la interfaz mientras se procesa.

El pipeline corre dentro de un Web Worker: se decodifica el audio con AudioContext, se mezcla a mono, y se ejecutan en paralelo varios análisis. Essentia.js (compilada a WebAssembly) detecta BPM y posiciones de beat con ML multifeature. Un FFT propio descompone el espectro en cuatro bandas. Un detector de onsets calcula la varianza de IOI para identificar trainwrecks (beats desincronizados durante una transición). Un motor de alertas cruza señales para detectar choques de graves, silencios muertos, fatiga auditiva y transiciones bruscas, con timestamps ajustados al beat más cercano.

Con todo eso se calcula una puntuación 0-100 con cuatro sub-métricas ponderadas (técnica, energía, flow, narrativa) y se desbloquean medallas. Y un sistema de detección automática para distinguir un mix real de un single track, para no mostrar puntuaciones a quien sube algo que no es un mix.

Proceso y decisiones

La decisión más importante fue procesar todo en cliente. El audio del DJ no se sube. Eso significa cero infraestructura de almacenamiento, cero costes variables por análisis y privacidad real por defecto. A cambio, todo el peso del análisis lo aguanta el navegador del usuario, así que la arquitectura tenía que estar bien.

El trabajo pesado vive en un Web Worker dedicado para no congelar la UI. Para los algoritmos de música (BPM, beats, key) se eligió Essentia.js compilado a WebAssembly, porque reescribir esos algoritmos a mano para llegar a la calidad de un MIR pro era inviable. Lo que Essentia no cubre bien (motor de alertas, scoring, detección de transiciones, IOI para trainwrecks) sí está hecho con DSP propio.

El modelo de negocio es dual. La versión individual tiene un free tier (analizar un set y ver el informe completo) que sirve de motor de adquisición, y funciones de cuenta (historial, progresión, medallas guardadas) detrás de login con Supabase. Por encima está la capa B2B para academias de DJ: plan Trial gratis 30 días, Starter (49€/mes), Pro (99€/mes) y Enterprise a medida. Los planes se cobran con Stripe.

Tracción

100% en navegadorProcesamiento
0 bytesAudio enviado al servidor
2 GBTamaño máximo por archivo
ES · EN · FR · DE (autodetección)Idiomas

¿Qué significa esto para tu proyecto?

Si tienes en mente una herramienta que tiene que procesar archivos pesados (audio, vídeo, imágenes, documentos) sin que el usuario los suba a un servidor, este proyecto demuestra que se puede montar. Web Audio API, Web Workers, integración de librerías compiladas a WebAssembly desde un stack React moderno y diseño con privacidad por defecto.

También sirve como ejemplo de SaaS con modelo dual B2C + B2B sobre la misma base de código. La app individual es freemium y funciona como motor de captación. Por encima hay un producto B2B para academias con panel de profesor, organizaciones (jerarquía teacher/student con RLS en Supabase), assignments con fecha y criterios, feedback del profesor visible al alumno, rúbricas personalizables (cada academia ajusta los pesos del scoring) y suscripciones con Stripe. Misma arquitectura encaja en otros productos donde un usuario individual se convierte luego en un usuario dentro de una organización que paga.

Y si necesitas integrar modelos ML o algoritmos pesados en una web moderna sin saltar a una infraestructura de Python/GPU, el patrón Essentia.js (WASM) + Web Workers se aplica igual a otros dominios: procesamiento de imagen, OCR, traducción local, análisis de texto. Misma lógica.

¿Quieres algo parecido?

Cuéntame qué tienes en mente y te digo qué puedo hacer.