VariaReEncoder / DEVLOG.md
Newer Older
95 lines | 3.849kb
Bogdan Timofte authored a month ago
1
# Development Log
2

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

            
5
---
6

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

            
9
### Language: Python → Bash
10

            
11
Started with Python 3 for portability (macOS/Linux/Windows). Switched to Bash after evaluating
12
supply-chain risk: a Python script tends to acquire `pip` dependencies over time, each one a
13
potential attack surface. Bash with only `ffmpeg`/`ffprobe` as external deps has a minimal,
14
auditable dependency surface.
15

            
16
Windows support was dropped as a result (Bash is not a first-class environment there).
17
Trade-off accepted: target platforms are macOS and Linux.
18

            
19
### Encoding strategy
20

            
21
Garmin Varia source clips are H.264, ~1080p, ~29.97fps, ~22 Mbps, ~30s duration, ~80-85 MB each.
22
The high bitrate is due to inefficient compression, not high visual complexity. Re-encoding with
23
CRF-based HEVC yields ~60-70% size reduction with no perceptible quality loss for this content type.
24

            
25
Bitrate is never derived mechanically from source file size. CRF (software) and constrained VBR
26
(hardware) are used instead, so the encoder allocates bits based on actual scene complexity.
27

            
28
### Default mode evolution
29

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

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

            
40
### Audio handling
41

            
42
ffprobe is called per-file to detect audio streams before building the ffmpeg command.
43
Source Garmin Varia clips contain PCM audio. Output is AAC 128k when audio is present;
44
no audio track is added if none is detected.
45

            
46
### Apple compatibility tag
47

            
48
HEVC outputs use `-tag:v hvc1` (not the default `hev1`). This is required for reliable
49
import and playback in Apple Photos and QuickTime Player.
50

            
51
### `--move-source` validation
52

            
53
Deleting originals is guarded by a three-step post-encode check:
54
1. Output file exists on disk
55
2. Codec matches expected (hevc or h264)
56
3. Duration within 1.0s of source
57

            
58
Source is only deleted if all three pass.
59

            
60
### Destination safety guard
61

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

            
65
### Bash 3.2 compatibility
66

            
67
macOS ships with Bash 3.2 (GPL v2). The script avoids:
68
- `local -n` (nameref, requires Bash 4.3+)
69
- `${var,,}` (lowercase expansion, requires Bash 4+)
70
- `extglob` patterns
71

            
72
### CLI defaults (final state)
73

            
74
| Flag | Default | Rationale |
75
|------|---------|-----------|
76
| `--recursive` | on | Tool is designed for large libraries with subdirectories |
77
| `--overwrite` | on | Filenames are timestamp-based (unique); no accidental overwrite risk |
78
| `--mode` | hardware | 96% less energy vs software on Apple Silicon |
79
| `--quiet` | on (default) | One progress line per file; verbose available via `--verbose` |
80

            
81
### Output verbosity
82

            
83
Default output is one line per file:
84
```
85
2026-05-04 12:08:00 : Transcoding SampleFootage/Day/clip.mp4 ... done in 5s
86
```
87
Paths are displayed relative to the working directory, not absolute, to keep lines short.
88
`--verbose` restores full per-operation logs and exposes ffmpeg/ffprobe output.
89

            
90
### Sidecar and manifest
91

            
92
JSON sidecars (Garmin activity metadata) are copied 1:1 alongside transcoded files.
93
`telemetry_manifest.json` is written as a placeholder contract for a future pipeline that
94
will parse Garmin FIT files and correlate telemetry (power, speed, HR, GPS) with video timestamps.
95
FIT parsing is not implemented in this release.