railcam is a CLI tool that turns raw climbing footage into clean, analysis-ready videos by automatically following the climber — as if filmed on a perfectly aligned vertical rail.
Designed for speed climbing analysis, coaching, and side-by-side comparisons, railcam uses AI pose estimation to lock onto the climber’s pelvis, producing smooth, tightly framed videos with consistent scale and zero manual editing.
⬇️ Example output generated by railcam (automatic tracking, normalized zoom, smooth vertical motion)
- No manual cropping or keyframing
- No shaky framing or inconsistent zoom
- No post-processing in a video editor
Just reproducible, normalized clips ready for performance analysis, coaching, or sharing.
-
AI-based climber tracking Automatic pelvis tracking using YOLOv8-pose for stable, body-anchored framing.
-
Dual-lane aware Reliably track the left or right climber in official speed walls and race footage.
-
Rail-like camera motion Smooth vertical tracking with interpolation and exponential smoothing.
-
Smart vertical crop (5:3) Tight framing optimized for climbers, with no black borders.
-
Automatic zoom normalization Consistent climber size based on torso height, across videos.
-
Side-by-side composition Compare multiple climbers or runs in a single synchronized output.
-
MP4 & GIF output High-quality H.264 MP4 or lightweight GIF.
-
Debug mode Pose skeleton overlay for inspection and validation.
-
Cross-platform macOS, Linux, Windows.
- Python 3.9+
- FFmpeg (video/GIF rendering)
Install FFmpeg:
# macOS
brew install ffmpeg
# Ubuntu / Debian
sudo apt install ffmpeg
# Windows
# Download from https://ffmpeg.org/download.htmlpip install .Development install:
pip install -e ".[dev]"
pre-commit install # Auto-setup git hooks (LFS check, linting)# Generate a tracked MP4
railcam video.mp4 100 250
# Track left climber on a dual-lane wall
railcam video.mp4 100 250 --climber left
# Side-by-side comparison
railcam \
--input video.mp4:100:250:left \
--input video.mp4:100:250:rightrailcam VIDEO START_FRAME END_FRAME [OPTIONS]Arguments
VIDEO– Input video fileSTART_FRAME– Start frame (0-indexed, inclusive)END_FRAME– End frame (0-indexed, inclusive)
railcam \
--input VIDEO1:START:END[:CLIMBER] \
--input VIDEO2:START:END[:CLIMBER] \
[OPTIONS]Each input is processed independently, then composed horizontally.
| Option | Description |
|---|---|
-i, --input PATH:START:END[:left|right] |
Input spec (repeatable) |
-c, --climber {left,right} |
Select climber |
-o, --output PATH |
Output path |
-f, --format {mp4,gif} |
Output format |
-w, --width PIXELS |
Output width |
-H, --height PIXELS |
Output height |
-s, --speed FACTOR |
Playback speed |
--debug |
Pose overlay |
-v, --version |
Show version |
-h, --help |
Show help |
- Extract frames from the requested range
- Detect poses with YOLOv8-pose
- Filter to climbers with visible pelvis
- Select and track the target climber
- Measure torso height (shoulder ↔ hip)
- Normalize zoom level
- Interpolate gaps and smooth motion
- Compute centered 5:3 crop
- Render MP4 or GIF via FFmpeg
- Average torso height is measured across frames
- Zoom adjusted so torso ≈ 1/3 of output height
- Zoom clamped between 1.0× and 3.0×
This ensures meaningful visual comparison across clips.
MP4 · AVI · MOV · MKV · WebM · M4V
railcam --helpMIT
