Transparent HUD overlay exporter for GoPro + Garmin athletes.
Motion Layer reads telemetry from GoPro Hero action cameras and Garmin activity files, synchronises both data sources, renders widget overlays on each video frame, and exports the result as a transparent ProRes 4444 .mov that you drop directly into your video editor like Adobe Premiere or DaVinci Resolve as an overlay track. It does not change your original footage.
Download Motion Layer from Releases.
Platform: Windows 10/11 | Standalone .exe - no installation required
If Motion Layer saves you time, consider supporting development:
- Import a GoPro
.mp4(Hero 5 and later), a Garmin.fitfile, or both together - Automatic UTC-based time sync between GoPro and Garmin recordings
- 8 configurable HUD widgets:
| Widget | Data source | Color coding |
|---|---|---|
| Speed | GoPro GPS or Garmin | Relative % of session max (blue → red) |
| Map | GoPro GPS or Garmin GPS | GPS trace with current position dot |
| G-Force | GoPro accelerometer | 0-1G blue / 1-2G yellow / 2G+ red |
| Heart Rate | Garmin | 5-zone HR coloring |
| Altitude | GoPro GPS or Garmin | With grade % when available |
| Cadence | Garmin | RPM |
| Power | Garmin | 5-zone watt coloring |
| Temperature | Garmin | Cold → hot color scale |
- Per-widget slot assignment (3×3 grid: TL / TC / TR / ML / MC / MR / BL / BC / BR)
- Per-widget background opacity slider
- Live preview with real video frame background
- Export resolutions: 720p, 1080p, 4K
- FPS locked to source video (no re-sampling artifacts)
- Output: ProRes 4444 with alpha - transparent background
Open the app and click the two drop zones to load your files.
- GoPro Video: Any
.mp4recorded with a Hero 5 or newer. GPS and sensors must be enabled on the camera while recording the footage. - Garmin Activity: Export the
.fitfile from Garmin Connect or copy it directly from theGARMIN/Activity/folder on your device.
You can load just the GoPro file, just the Garmin file, or both. Widgets whose data source is not loaded are hidden automatically.
Arrange and configure your widgets:
- Toggle each widget on or off
- Slot - pick one of the 9 positions on the 3×3 grid
- Opacity - drag the slider to adjust background transparency (0 = fully transparent, 100 = solid black)
The canvas preview shows your actual video frame with the overlay on top.
Choose your output resolution (720p / 1080p / 4K) and click Export.
The output file is saved next to your source video as filename_overlay.mov.
Import this file into your NLE:
- Adobe Premiere Pro: Drop
_overlay.movon a track above your footage. Set blend mode to Normal. The transparent alpha is preserved automatically. - DaVinci Resolve: Same approach - place it on a track above your video clip.
Note: VLC does not render ProRes 4444 alpha correctly (shows black). This is expected behaviour - use video editors like Premiere or Resolve for playback.
| Device | Status |
|---|---|
| GoPro Hero 5 / 6 / 7 | GPS5 stream |
| GoPro Hero 8 / 9 / 10 / 11 / 12 | GPS5 / GPS9 stream |
| Any Garmin device (GPS watch, cycling computer) | .fit via Garmin Connect |
GoPro recording tips for best results:
- Enable GPS in camera settings (Settings → Preferences → GPS)
- Start recording outdoors - GPS lock takes 30–60 seconds; indoor starts leave a gap at the beginning
- Do not power via USB while recording (may disable GPS on some models)
- Node.js 20+
- npm
git clone https://github.com/alisezisli/motion-layer
cd motion-layer
npm install
npm run dev # hot-reload dev modenpm run build # TypeScript + Vite bundle (output: out/)
npm run dist # Electron packager → dist/MotionLayer.exe (~150-200 MB)The packaged .exe is fully self-contained: ffmpeg, ffprobe, and the canvas native binary are all bundled inside.
All visual constants live in two central objects - no hunting through component files:
| What | Where |
|---|---|
| UI colors, font sizes | src/renderer/src/theme.ts → THEME |
| Widget colors, font sizes, opacity | src/main/renderer.ts → OVERLAY |
| Widget default positions & states | src/renderer/src/App.tsx → DEFAULT_WIDGETS |
| Color zone thresholds (speed, HR, power, temperature) | src/main/renderer.ts → individual render*() functions |
If Motion Layer saves you time, consider supporting development:

