Heb je ooit gewenst dat je een fietsroute kon bekijken voordat je hem rijdt? We hebben een geautomatiseerd systeem gebouwd dat prachtige flyover-video’s genereert voor elke feestroute op Party Onbici, waardoor fietsers een cinematografische preview krijgen van wat ze op hun reis kunnen verwachten.

De Uitdaging

Bij het organiseren van of deelnemen aan een fietsevenement is het begrijpen van de route cruciaal. Statische kaarten zijn nuttig, maar ze brengen niet de ervaring over van het daadwerkelijk rijden van de route. We wilden gebruikers een manier geven om virtueel “door de route te vliegen” voordat ze zich aan een rit committeren.

Onze Oplossing: Headless Video Rendering

We hebben een Node.js-service gebouwd die een headless Chrome-browser draait met Puppeteer, de route rendert op een interactieve MapLibre GL-kaart en frames vastlegt terwijl een virtuele camera langs het pad vliegt. Zo werkt het:

1. Route Interpolatie

Een fietsroute kan duizenden coordinaatpunten hebben. Om een vloeiende video te maken van 30 FPS gedurende 15 seconden, hebben we precies 450 frames nodig. We gebruiken afstandsgebaseerde interpolatie om de route gelijkmatig te samplen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// Calculate cumulative distances using Haversine formula
const distances = [0];
for (let i = 1; i < coordinates.length; i++) {
  const dist = haversineDistance(coordinates[i-1], coordinates[i]);
  totalDistance += dist;
  distances.push(totalDistance);
}

// Sample at exactly totalFrames points
for (let frame = 0; frame < totalFrames; frame++) {
  const targetDist = (frame / (totalFrames - 1)) * totalDistance;
  // Interpolate position at this distance...
}

2. Camera Animatie met Vloeiende Richting

Simpelweg de camera richten in de reisrichting creëert schokkerige beweging op bochtige routes. We verzachten de camerarichting met een voortschrijdend gemiddelde over 12 frames, met speciale behandeling voor de 360 graden/0 graden overgang:

1
2
3
4
5
6
7
// Use sin/cos components for circular averaging
for (let j = i - smoothWindow; j <= i + smoothWindow; j++) {
  const rad = rawBearings[j] * Math.PI / 180;
  sinSum += Math.sin(rad);
  cosSum += Math.cos(rad);
}
const avgBearing = Math.atan2(sinSum/count, cosSum/count) * 180 / Math.PI;

3. MapLibre GL Rendering

De route wordt gerenderd op een mooie Stadia Maps basislaag met:

  • Een gemarkeerde routelijn met witte omtrek voor zichtbaarheid
  • Geanimeerde camerapositie-indicator
  • Start (groen) en finish (rood) markers
  • Optionele 3D-gebouwextrusies voor stedelijke gebieden

4. Frame Capture en Video Encoding

Puppeteer vangt elk frame als PNG-screenshot, daarna gebruiken we ffmpeg om ze te encoderen in een WebM-video met VP9-codec:

1
2
3
ffmpeg -framerate 30 -i frame_%05d.png \
  -c:v libvpx-vp9 -crf 20 -b:v 0 \
  route.webm

Technische Architectuur

1
Django App → Celery Task → Node.js Renderer → S3 Storage
  1. Django activeert videogeneratie wanneer een feest wordt aangemaakt of bijgewerkt
  2. Celery plaatst de taak in de wachtrij voor asynchrone verwerking
  3. Node.js renderer draait Puppeteer met MapLibre GL
  4. ffmpeg encodeert de vastgelegde frames
  5. Video wordt geupload naar S3 en het feestrecord wordt bijgewerkt

Prestatie Overwegingen

ResolutieDuurRendertijdBestandsgrootte
1280x72015s60-90s2-4 MB
1920x108015s90-120s4-8 MB

Voor productie gebruiken we Docker-containers met software rendering (SwiftShader) om GPU-afhankelijkheden te vermijden:

1
2
--use-angle=swiftshader
--enable-unsafe-swiftshader

Functies die We Hebben Toegevoegd

  • Aanpasbare video-afmetingen - Vierkant formaat voor delen op sociale media
  • Logo watermerking - Merk je video’s met het logo van je organisatie
  • Camera kantel en zoom - Pas de kijkhoek en hoogte aan
  • Routelijn styling - Aangepaste kleuren en breedtes

Django Integratie

Vanuit de applicatiecode is het genereren van een video zo simpel als:

1
2
party = Party.objects.get(uid="...")
party.generate_video(width=1080, height=1080, duration=10)

De video-URL wordt automatisch bijgewerkt wanneer het renderen is voltooid:

1
2
3
4
5
{% if party.video_url %}
<video controls>
  <source src="{{ party.video_full_url }}" type="video/webm">
</video>
{% endif %}

Volgende Stappen

We onderzoeken verschillende verbeteringen:

  • Real-time preview - Live renderen terwijl gebruikers routes tekenen
  • Meerdere camerahoeken - Zijaanzichten, bovenaanzichten
  • Weer overlay - Toon voorspelde omstandigheden langs de route
  • Hoogteprofiel - Visualiseer klimmen en dalen in de video

Route flyover-video’s zijn een van onze populairste functies geworden en helpen fietsers weloverwogen beslissingen te nemen over welke ritten ze willen doen. De combinatie van moderne webtechnologieen maakt van wat een dure productietaak zou zijn geweest een geautomatiseerde, on-demand service.


Wil je het uitproberen? Maak een feest aan en je routevideo wordt automatisch gegenereerd!