Saltar al contenido principal

Sección

Tecnología

La pila real de Dueli en dos capas: una explicación en lenguaje sencillo y la vista de ingeniería.

Esta página explica las tecnologías que Dueli realmente utiliza, en dos capas: una vista en lenguaje sencillo para todos y una vista de ingeniería para especialistas. No se lista ninguna tecnología a menos que el código actual la utilice.

En términos sencillos

Dueli funciona en el navegador en la red global de Cloudflare. Dos competidores se encuentran en una llamada de video en vivo entre sus dispositivos (WebRTC peer-to-peer); cuando una red bloquea la ruta directa, un relé TURN ayuda a la conexión.

Durante una competencia, el navegador combina ambas transmisiones de cámara en una sola imagen y la registra en fragmentos de 5 segundos. Los fragmentos se suben a medida que se producen, pueden reproducirse en orden y se ensamblan en una repetición completa después de que termina el duelo.

Las competencias grabadas se pueden descargar como archivo MP4. Cuando una grabación necesita conversión, la conversión se ejecuta dentro del navegador del visitante con FFmpeg.wasm, por lo que el archivo no se envía a un servicio de conversión externo.

Los datos de la plataforma viven en D1, las páginas y las API se construyen con Hono y TypeScript en Cloudflare, y la interfaz utiliza Tailwind CSS. Las actualizaciones en vivo llegan a través de SSE y sondeo.

Para ingenieros

Tiempo de ejecución: Cloudflare Pages/Workers con Hono 4 en TypeScript. D1 (SQLite) es la base de datos. Vite construye el paquete del Worker, Tailwind CSS 4 estiliza la interfaz, y esbuild empaqueta los puntos de entrada del navegador.

Medios en vivo: una conexión RTCPeerConnection del navegador transporta WebRTC entre el anfitrión y el oponente. Los servidores ICE se emiten por sesión desde GET /api/signaling/ice-servers; Cloudflare Calls TURN (TURN_TOKEN_ID y TURN_API_TOKEN) o coturn autohospedado (TURN_URL y TURN_SECRET) pueden retransmitir, con un respaldo solo STUN cuando ninguno está configurado.

Grabación: un compositor de canvas dibuja ambas transmisiones, y MediaRecorder emite un fragmento cada 5 segundos. El anfitrión registra cada fragmento en POST /api/chunks/register (una clave de un solo uso de corta duración vinculada a la competencia, secuencia y límite de bytes), lo sube, lo verifica con GET /verify y reporta en POST /receipt. La reproducción lee GET /api/chunks/playlist/:id, y el paso de finalización existente produce el VOD.

Descargas: @ffmpeg/core 0.12.10 se ejecuta en un worker del navegador autohospedado para la conversión MP4, con una ruta de remux estructural para grabaciones ya compatibles con MP4. El progreso y los límites de memoria se manejan en el servicio del cliente.

Tiempo real: SSE a través de GET /api/sse transporta actualizaciones en vivo, y la señalización usa sondeo HTTP; la ruta de producción no utiliza WebSocket.

Calidad: Vitest cubre las pruebas unitarias y los contratos de UI, y Playwright cubre los flujos de navegador de extremo a extremo. Los documentos Markdown se renderizan con marked, y PostCSS con Autoprefixer completa la canalización CSS.

La pila en este repositorio

  • Cloudflare Pages / Workers Hosting y tiempo de ejecución del servidor
  • Cloudflare D1 (SQLite) Base de datos de la aplicación
  • Hono 4 Rutas HTTP, páginas y API
  • TypeScript 5 Código fuente tipado para servidor y cliente
  • Tailwind CSS 4 + PostCSS + Autoprefixer Estilo de interfaz y canalización CSS
  • Vite 7 + esbuild Empaquetado del worker y puntos de entrada del navegador
  • WebRTC (RTCPeerConnection) + TURN/STUN Audio y video en vivo entre participantes
  • Compositor de Canvas + MediaRecorder Fragmentos grabados de 5 segundos en el navegador
  • FFmpeg.wasm (@ffmpeg/core 0.12.10) Conversión y descarga de MP4 en el navegador
  • marked 17 Renderizado de Markdown para documentos gestionados
  • Vitest 5 Suite de pruebas unitarias y de UI
  • Playwright Pruebas de extremo a extremo en el navegador
  • Wrangler 4 Herramientas de desarrollo y despliegue de Cloudflare
  • SSE + sondeo HTTP Actualizaciones en vivo fuera de la ruta de medios

La lista está limitada a lo que package.json y el repositorio realmente contienen. Es una descripción técnica, no una declaración de asociación o respaldo.

Volver al centro de la guía