A PyQt6-based desktop application for parsing MoTeC .ld telemetry files and overlaying real-time telemetry data onto video recordings.
- Parse MoTeC LD telemetry files with GPS support
- Visualize telemetry data with configurable overlays:
- Gauge Overlay: Combined RPM needle, shift lights, and speed readout
- G-G Diagram: Lateral and longitudinal G-force scatter plot with trail history
- Input HUD: Throttle, brake, and steering input display
- Bar Overlay: Generic telemetry bar for throttle/brake/any scalar channel
- Text Overlay: Generic telemetry text readout with format options
- GPS Track: Track map showing current position ± 10 seconds
- Video player with draggable overlays
- Dual-handle timeline range selection for export in/out
- Plot-based sync workflow using fixed-width telemetry selection window
- Drag-and-drop overlay positioning
- Offline FFmpeg export with burned-in overlays (MP4/H.264 + AAC)
- Export progress, cancel, overwrite warning, and done state in export dialog
uv syncuv run main.pyCommand line options:
uv run main.py --ld-file path/to/data.ld --video-file path/to/video.mp4
uv run main.py --config path/to/config.json- Load telemetry with LD File....
- Load video with Video File....
- Click Parse to populate channels.
- Select channels to display in telemetry plots.
- Set video in/out segment using timeline range handles.
- Move the plot selection window to align telemetry with video (this sets sync offset).
- Click Export and choose output path/quality.
- Drag telemetry selection window to change sync offset.
- Arrow keys on plot window: nudge by 1.0s.
- Shift + Arrow: nudge by 0.1s.
- Hold Arrow for ~3s: nudge by 10.0s steps.
├── main.py # Entry point
├── config.py # Application configuration constants
├── parsers/
│ ├── ldparser.py # MoTeC LD file parser
│ └── gps_parser.py # GPS coordinate utilities
├── models/
│ ├── telemetry_data.py # Parsed telemetry container
│ ├── channel.py # Single channel data/interpolation
│ └── overlay_instance.py # Overlay config/state model
├── widgets/
│ ├── gauge_overlay.py # Combined RPM/speed gauge overlay
│ ├── gg_diagram.py # G-force diagram
│ ├── bar_overlay.py # Generic telemetry bar overlay
│ ├── text_overlay.py # Generic telemetry text overlay
│ ├── logo_overlay.py # Image/logo overlay
│ ├── input_hud.py # Throttle/brake/steering input HUD
│ ├── gps_track.py # GPS track map
│ ├── channel_plot.py # Time-series plot + fixed selection region
│ ├── multi_channel_plot.py # Linked stack of channel plots
│ └── range_slider.py # Timeline with range handles + playhead
├── views/
│ ├── main_window.py # Main application window
│ ├── video_player.py # QMediaPlayer + timeline + overlay scene
│ ├── settings_panel.py # Overlay settings UI
│ └── export_dialog.py # Export options/progress dialog
├── controllers/
│ └── export_renderer.py # Offline FFmpeg export renderer
└── utils/
├── math_utils.py
└── theme.py
- Python 3.12+
- PyQt6
- pyqtgraph
- numpy
- FFmpeg (
ffmpegandffprobeavailable inPATH)
uv run ruff check .
uv run ruff format --check .
uv run python -m py_compile main.py config.py views/main_window.py views/settings_panel.py views/video_player.py controllers/export_renderer.py widgets/*.py models/*.py parsers/*.py utils/*.py