# Development Log

Decisions, trade-offs, and rationale recorded during development of `garmin_varia_transcode.sh`.

---

## 2026-05-04 — Initial design and implementation

### Language: Python → Bash

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.

### Encoding strategy

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.

### Default mode evolution

1. `auto` — initial default; cross-platform safe
2. `quality` (libx265) — changed to maximize archival quality
3. `hardware` (hevc_videotoolbox) — **final default**, after measuring on Apple Silicon MacBook Pro:
   - hardware: ~4-5s per clip, ~35W (~0.049 Wh/clip)
   - software: ~50s per clip, ~80W (~1.18 Wh/clip)
   - Energy difference: ~96% less energy per clip with hardware encoding
   - Quality difference for dashcam footage: negligible

`auto` is still available as a cross-platform fallback.

### Audio handling

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.

### Apple compatibility tag

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` validation

Deleting 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.

### Destination safety guard

If destination is inside source, the script exits with an error. This prevents `find` from
recursing into partially-written output files during a run.

### Bash 3.2 compatibility

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

### CLI defaults (final state)

| 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` |

### Output verbosity

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.

