Decisions, trade-offs, and rationale recorded during development of garmin_varia_transcode.sh.
Started with Python 3 for portability (macOS/Linux/Windows). Switched to Bash after evaluating
supply-chain risk: a Python script tends to acquire pip dependencies over time, each one a
potential attack surface. Bash with only ffmpeg/ffprobe as external deps has a minimal,
auditable dependency surface.
Windows support was dropped as a result (Bash is not a first-class environment there). Trade-off accepted: target platforms are macOS and Linux.
Garmin Varia source clips are H.264, ~1080p, ~29.97fps, ~22 Mbps, ~30s duration, ~80-85 MB each. The high bitrate is due to inefficient compression, not high visual complexity. Re-encoding with CRF-based HEVC yields ~60-70% size reduction with no perceptible quality loss for this content type.
Bitrate is never derived mechanically from source file size. CRF (software) and constrained VBR (hardware) are used instead, so the encoder allocates bits based on actual scene complexity.
auto — initial default; cross-platform safequality (libx265) — changed to maximize archival qualityhardware (hevc_videotoolbox) — final default, after measuring on Apple Silicon MacBook Pro:
auto is still available as a cross-platform fallback.
ffprobe is called per-file to detect audio streams before building the ffmpeg command. Source Garmin Varia clips contain PCM audio. Output is AAC 128k when audio is present; no audio track is added if none is detected.
HEVC outputs use -tag:v hvc1 (not the default hev1). This is required for reliable
import and playback in Apple Photos and QuickTime Player.
--move-source validationDeleting originals is guarded by a three-step post-encode check: 1. Output file exists on disk 2. Codec matches expected (hevc or h264) 3. Duration within 1.0s of source
Source is only deleted if all three pass.
If destination is inside source, the script exits with an error. This prevents find from
recursing into partially-written output files during a run.
macOS ships with Bash 3.2 (GPL v2). The script avoids:
- local -n (nameref, requires Bash 4.3+)
- ${var,,} (lowercase expansion, requires Bash 4+)
- extglob patterns
| Flag | Default | Rationale |
|---|---|---|
--recursive |
on | Tool is designed for large libraries with subdirectories |
--overwrite |
on | Filenames are timestamp-based (unique); no accidental overwrite risk |
--mode |
hardware | 96% less energy vs software on Apple Silicon |
--quiet |
on (default) | One progress line per file; verbose available via --verbose |
Default output is one line per file:
2026-05-04 12:08:00 : Transcoding SampleFootage/Day/clip.mp4 ... done in 5s
Paths are displayed relative to the working directory, not absolute, to keep lines short.
--verbose restores full per-operation logs and exposes ffmpeg/ffprobe output.
JSON sidecars (Garmin activity metadata) are copied 1:1 alongside transcoded files.
telemetry_manifest.json is written as a placeholder contract for a future pipeline that
will parse Garmin FIT files and correlate telemetry (power, speed, HR, GPS) with video timestamps.
FIT parsing is not implemented in this release.