Ever wished you could preview a cycling route before you ride it? We built an automated system that generates beautiful flyover videos for every party route on Party Onbici, giving riders a cinematic preview of what to expect on their journey.
The Challenge
When organizing or joining a cycling event, understanding the route is crucial. Static maps are helpful, but they don’t convey the experience of actually riding the route. We wanted to give users a way to virtually “fly through” the route before committing to a ride.
Our Solution: Headless Video Rendering
We built a Node.js service that runs a headless Chrome browser using Puppeteer, renders the route on an interactive MapLibre GL map, and captures frames as a virtual camera flies along the path. Here’s how it works:
1. Route Interpolation
A cycling route might have thousands of coordinate points. To create a smooth video at 30 FPS for a 15-second duration, we need exactly 450 frames. We use distance-based interpolation to sample the route evenly:
| |
2. Camera Animation with Smooth Bearing
Simply pointing the camera in the direction of travel creates jerky motion on winding routes. We smooth the camera bearing using a moving average over 12 frames, with special handling for the 360°/0° wraparound:
| |
3. MapLibre GL Rendering
The route is rendered on a beautiful Stadia Maps base layer with:
- A highlighted route line with white outline for visibility
- Animated camera position indicator
- Start (green) and end (red) markers
- Optional 3D building extrusions for urban areas
4. Frame Capture and Video Encoding
Puppeteer captures each frame as a PNG screenshot, then we use ffmpeg to encode them into a WebM video with VP9 codec:
| |
Technical Architecture
| |
- Django triggers video generation when a party is created or updated
- Celery queues the task for async processing
- Node.js renderer runs Puppeteer with MapLibre GL
- ffmpeg encodes the captured frames
- Video is uploaded to S3 and the party record is updated
Performance Considerations
| Resolution | Duration | Render Time | File Size |
|---|---|---|---|
| 1280x720 | 15s | 60-90s | 2-4 MB |
| 1920x1080 | 15s | 90-120s | 4-8 MB |
For production, we use Docker containers with software rendering (SwiftShader) to avoid GPU dependencies:
| |
Features We Added
- Customizable video dimensions - Square format for social media sharing
- Logo watermarking - Brand your videos with your organization’s logo
- Camera pitch and zoom - Adjust the viewing angle and altitude
- Route line styling - Custom colors and widths
Django Integration
From the application code, generating a video is as simple as:
| |
The video URL is automatically updated when rendering completes:
| |
What’s Next
We’re exploring several enhancements:
- Real-time preview - Live rendering as users draw routes
- Multiple camera angles - Side views, overhead shots
- Weather overlay - Show forecast conditions along the route
- Elevation profile - Visualize climbs and descents in the video
Route flyover videos have become one of our most popular features, helping cyclists make informed decisions about which rides to join. The combination of modern web technologies makes what would have been an expensive production task into an automated, on-demand service.
Want to try it out? Create a party and your route video will be automatically generated!
