commit 98026e0087d2306c1080ccd290a2c7f2ac8ab9e4 Author: Erhan Keseli Date: Tue Jan 20 20:20:14 2026 +0100 Initial commit: M4 Pro optimized overlay pipeline diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..270f46f --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +# Python +__pycache__/ +venv/ +*.pyc + +# Mac OS +.DS_Store + +# Media Files (Do not commit these!) +*.mp4 +*.mov +*.mkv +*.fit +*.gpx + +# Output files +overlay_* diff --git a/README.md b/README.md new file mode 100644 index 0000000..14da733 --- /dev/null +++ b/README.md @@ -0,0 +1,49 @@ +# Garmin Video Edit + +This project provides a streamlined workflow for overlaying Garmin telemetry data onto video files, specifically optimized for macOS (M4 Pro). It utilizes the `gopro-overlay` toolset to generate high-quality data visualizations from Garmin `.fit` files. + +## Prerequisites + +- **Python 3.12+** +- **FFmpeg** (installed via Homebrew: `brew install ffmpeg`) +- **macOS** (Optimized for Apple Silicon hardware acceleration) + +## Setup + +1. **Create and activate a virtual environment:** + ```bash + python3 -m venv venv + source venv/bin/activate + ``` + +2. **Install dependencies:** + ```bash + pip install -r requirements.txt + ``` + +## Files + +- `render.sh`: The main script to trigger the rendering process. +- `ffmpeg-profiles.json`: Custom FFmpeg profiles, including `m4-youtube` for hardware-accelerated H.264 encoding. +- `pro_layout.xml` / `power_layout.xml`: Custom XML layout definitions for the data overlay. +- `Roboto-Medium.ttf`: The font used for the overlay text. + +## Usage + +To render a video with a Garmin telemetry overlay, use the `render.sh` script: + +```bash +./render.sh +``` + +### Example: +```bash +./render.sh 21595187246_ACTIVITY.fit footage.mp4 +``` + +The script will generate an output file named `overlay_footage.mov` (where `footage` is the original filename). + +## Configuration + +- **Layouts**: You can switch between `pro_layout.xml` and `power_layout.xml` by editing the `render.sh` script or modifying the command line arguments. +- **Hardware Acceleration**: The `m4-youtube` profile in `ffmpeg-profiles.json` is configured to use `h264_videotoolbox` for fast rendering on macOS. diff --git a/Roboto-Medium.ttf b/Roboto-Medium.ttf new file mode 100644 index 0000000..d629e98 Binary files /dev/null and b/Roboto-Medium.ttf differ diff --git a/ffmpeg-profiles.json b/ffmpeg-profiles.json new file mode 100644 index 0000000..0e6f556 --- /dev/null +++ b/ffmpeg-profiles.json @@ -0,0 +1,10 @@ +{ + "m4-youtube": { + "input": [], + "output": [ + "-c:v", "h264_videotoolbox", + "-b:v", "50000k", + "-profile:v", "high" + ] + } +} diff --git a/power_layout.xml b/power_layout.xml new file mode 100644 index 0000000..e2a0b27 --- /dev/null +++ b/power_layout.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/pro_layout.xml b/pro_layout.xml new file mode 100644 index 0000000..aaf0583 --- /dev/null +++ b/pro_layout.xml @@ -0,0 +1,22 @@ + + + + + + + KM/H + + + + + + WATTS + + + + RPM + + + + BPM + diff --git a/render.sh b/render.sh new file mode 100755 index 0000000..af54e5a --- /dev/null +++ b/render.sh @@ -0,0 +1,76 @@ +#!/bin/bash + +# ============================================================================== +# Garmin Overlay Render Script for macOS (M4 Pro Optimized) +# Usage: ./render.sh +# ============================================================================== + +# 1. Validate Arguments +if [ "$#" -ne 2 ]; then + echo "Error: Invalid number of arguments." + echo "Usage: ./render.sh " + echo "Example: ./render.sh activity.fit footage.mp4" + exit 1 +fi + +# 2. Define Variables +FIT_FILE="$1" +VIDEO_FILE="$2" + +# Extract filename without extension to auto-generate output name +BASENAME=$(basename "$VIDEO_FILE") +FILENAME="${BASENAME%.*}" +# Output format is .mov because we are using H.264/ProRes containers +OUTPUT_FILE="overlay_${FILENAME}.mov" + +# 3. Check and Activate Virtual Environment +# This assumes the script is run from the project root where 'venv' exists +if [ -d "venv" ]; then + source venv/bin/activate +else + echo "Error: 'venv' directory not found. Please run this script from the project root." + exit 1 +fi + +# 4. Check for Dependencies +if [ ! -f "pro_layout.xml" ] || [ ! -f "ffmpeg-profiles.json" ]; then + echo "Error: Configuration files (pro_layout.xml or ffmpeg-profiles.json) are missing." + exit 1 +fi + +echo "================================================================" +echo "Starting Render Process" +echo "================================================================" +echo "FIT Data : $FIT_FILE" +echo "Video Input : $VIDEO_FILE" +echo "Output File : $OUTPUT_FILE" +echo "Profile : m4-youtube (Hardware Accelerated H.264)" +echo "Layout : pro_layout.xml" +echo "Timestamp : $(date)" +echo "================================================================" + +# 5. Execute gopro-dashboard.py +# Using --use-gpx-only to ignore GoPro metadata and force external FIT data +gopro-dashboard.py \ + --use-gpx-only \ + --gpx "$FIT_FILE" \ + --layout xml \ + --layout-xml pro_layout.xml \ + --overlay-size 3840x2160 \ + --units-speed kph \ + --units-altitude meter \ + --font "Roboto-Medium.ttf" \ + --config-dir . \ + --profile m4-youtube \ + "$VIDEO_FILE" "$OUTPUT_FILE" + +# 6. Completion +if [ $? -eq 0 ]; then + echo "================================================================" + echo "SUCCESS: Render finished. Output saved to: $OUTPUT_FILE" + echo "================================================================" +else + echo "================================================================" + echo "FAILURE: An error occurred during rendering." + echo "================================================================" +fi diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..f9287d8 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +gopro-overlay +fitdecode +pycairo