Sectie
Technologie
De echte Dueli-stack in twee lagen: een uitleg in gewone taal en de technische ingenieursblik.
Deze pagina legt de technologieën uit die Dueli daadwerkelijk gebruikt, in twee lagen: een weergave in gewone taal voor iedereen en een ingenieursweergave voor specialisten. Er wordt geen technologie genoemd tenzij de huidige code die gebruikt.
In gewone taal
Dueli draait in de browser op het wereldwijde netwerk van Cloudflare. Twee deelnemers treffen elkaar in een live videogesprek tussen hun apparaten (WebRTC peer-to-peer); wanneer een netwerk de directe route blokkeert, helpt een TURN-relay de verbinding tot stand te brengen.
Tijdens een competitie combineert de browser beide camerabeelden tot één beeld en neemt dat op in korte fragmenten van 5 seconden. De fragmenten worden geüpload zodra ze gemaakt zijn, kunnen op volgorde worden teruggekeken en worden na afloop van de wedstrijd samengevoegd tot een volledige herhaling.
Opgenomen competities kunnen worden gedownload als MP4-bestand. Wanneer een opname moet worden geconverteerd, gebeurt dat in de browser van de bezoeker met FFmpeg.wasm, zodat het bestand niet naar een externe conversiedienst wordt gestuurd.
Platformgegevens staan in D1, pagina's en API's zijn gebouwd met Hono en TypeScript op Cloudflare, en de interface gebruikt Tailwind CSS. Live updates komen binnen via SSE en polling.
Voor ingenieurs
Runtime: Cloudflare Pages/Workers met Hono 4 op TypeScript. D1 (SQLite) is de database. Vite bouwt de Worker-bundel, Tailwind CSS 4 verzorgt de styling van de interface en esbuild bundelt de browseringangspunten.
Live media: een RTCPeerConnection in de browser verzorgt WebRTC tussen host en tegenstander. ICE-servers worden per sessie verstrekt via GET /api/signaling/ice-servers; Cloudflare Calls TURN (TURN_TOKEN_ID en TURN_API_TOKEN) of zelf-gehoste coturn (TURN_URL en TURN_SECRET) kan als relay dienen, met een terugval op alleen-STUN wanneer geen van beide is ingesteld.
Opname: een canvas-compositor tekent beide beelden en MediaRecorder levert elke 5 seconden een fragment aan. De host registreert elk fragment via POST /api/chunks/register (een kortlevende eenmalige sleutel, gekoppeld aan de competitie, de volgorde en de bytelimiet), uploadt het, verifieert het via GET /verify en meldt POST /receipt. Afspelen leest GET /api/chunks/playlist/:id, en de bestaande afrondstap levert de VOD op.
Downloads: @ffmpeg/core 0.12.10 draait in een zelf-gehoste browserworker voor MP4-conversie, met een structureel remux-pad voor opnames die al MP4-compatibel zijn. Voortgang en geheugenlimieten worden afgehandeld in de clientservice.
Realtime: SSE via GET /api/sse brengt live updates over, en signalering gebruikt HTTP-polling; het productiepad gebruikt geen WebSocket.
Kwaliteit: Vitest dekt unit- en UI-contracten af, en Playwright dekt end-to-end browserstromen af. Markdown-documenten worden gerenderd met marked, en PostCSS met Autoprefixer maakt de CSS-pijplijn compleet.
De stack in deze repository
- Cloudflare Pages / Workers Hosting en serverruntime
- Cloudflare D1 (SQLite) Applicatiedatabase
- Hono 4 HTTP-routes, pagina's en API
- TypeScript 5 Getypeerde broncode voor server en client
- Tailwind CSS 4 + PostCSS + Autoprefixer Interfacestyling en CSS-pijplijn
- Vite 7 + esbuild Worker-bundel en browseringangspunten
- WebRTC (RTCPeerConnection) + TURN/STUN Live audio en video tussen deelnemers
- Canvas compositor + MediaRecorder Opnamefragmenten van 5 seconden in de browser
- FFmpeg.wasm (@ffmpeg/core 0.12.10) MP4-conversie en download in de browser
- marked 17 Markdown-rendering voor beheerde documenten
- Vitest 5 Testsuite voor unit- en UI-tests
- Playwright End-to-end browsertests
- Wrangler 4 Cloudflare-tooling voor ontwikkeling en uitrol
- SSE + HTTP-polling Live updates buiten het mediapad
De lijst beperkt zich tot wat package.json en de repository daadwerkelijk bevatten. Het is een technische beschrijving, geen claim van partnerschap of aanbeveling.