Expand description
Listing finished/in-progress capture runs on disk — the reusable read side of the timelapse feature, so the CLI and the server present the same recordings.
A serve capture writes to captures/<epoch>_<name>_<mode>/<camera-id>/, where each
camera dir holds one of: park_NNNNNN.jpg (a park-detected clean timelapse),
frame_NNNNNN_*.jpg (a printer-synced smooth timelapse), or plain.mp4 / plain.mjpeg
(a head-in-shot video). The kind is detected from the files, not the dir name (older
runs lacked the _<mode> suffix), so it stays correct across layout changes.
The filename → kind classification is pure (unit-tested); walking the directory is the thin I/O wrapper (tested with a temp tree).
Structs§
- Capture
Cam - One camera’s output within a run.
- Capture
Run - One capture run (a print’s recordings), newest first when listed.
Enums§
- Capture
Kind - What a camera’s capture dir holds.
Constants§
- SMOOTH_
DECODE_ H - SMOOTH_
DECODE_ W - Decode size for smooth burst selection — tiny gray, matching the live park detector and the skill’s select_smooth.py (enough signal for the left-zone park, cheap to score).
Functions§
- assemble_
args - ffmpeg argv (after the program name) to assemble a camera dir’s image sequence into
outatfps.Nonefor a Video kind (it’s already a file — nothing to assemble). Park frames are a contiguouspark_%06d.jpg; smooth frames sort lexicographically, so glob them. Pure, so the command shape is unit-tested without ffmpeg. - assemble_
mp4 - Assemble a camera dir’s image sequence to an mp4 at
out(overwriting). Shared by the CLI’s--assembleand the server. Errors if the kind isn’t an image sequence. - assemble_
selected_ mp4 - Assemble a specific, ordered list of full-res JPEGs into an mp4 (the selected parked
frames). Stages them as a contiguous
sel_%06d.jpgsequence in a temp subdir next toout, image2-assembles, then cleans up. - assemble_
smooth_ selected_ mp4 - The clean smooth timelapse: select the parked frame per layer, then assemble just those. Errors (and the caller falls back to the raw all-frames assemble) if nothing selectable.
- classify
- Classify a camera dir from its filenames (pure).
Nonewhen nothing recognizable is present (e.g. an empty dir or a transient.ring). - extract_
video_ thumb - Extract a poster still from a video recording (the thin ffmpeg seam for Video thumbs).
- gray_
decode_ args - ffmpeg argv to decode every JPEG matching
globto aw×hgray rawvideo stream on stdout (one frame after another, glob = capture order). One ffmpeg for the whole set — no per-frame spawn. Pure (command shape unit-tested without ffmpeg). - list_
captures - List capture runs under
root(newest first). Each run’s cameras are its per-camera subdirs that hold recognizable output; an older single-dir run (files directly in the run dir) surfaces as one camera with an empty id. Best-effort: unreadable dirs are skipped, never an error. - parse_
run_ id - Split a run dir name into (epoch, label):
1781634785_cube_gcode_3mf→ (1781634785, “cube_gcode_3mf”). A non-numeric/absent prefix yields(0, whole-name). - parse_
smooth_ frame - Parse a smooth burst frame name
frame_<n>_layer_<L>_t<offset>.jpg→(layer, offset_ms).Nonefor anything that isn’t a burst frame. Pure. - select_
layer_ burst - Decode + select the parked frame from ONE layer’s burst — the live path used during a
smooth capture (after each layer’s burst settles). Decodes just that layer’s
frame_*_layer_<L>_t*.jpgwith one ffmpeg and runsselect_park_frame. Returns the chosen full-res JPEG path, orNoneif the layer’s park wasn’t captured. - select_
smooth_ frames - Pick the parked frame from each layer’s burst in a smooth cam dir, returning the chosen
full-res JPEG paths in layer order. Decodes the whole dir to tiny gray with ONE ffmpeg,
groups by layer, and runs the pure
select_park_frame. Layers whose park fell outside the burst are skipped (a gap beats a head-over-print frame). - smooth_
decode_ args - Decode args for all
frame_*.jpgin a smooth cam dir (whole-run selection). - thumb_
frame - The representative still for a recording’s thumbnail: the LAST frame of an image
sequence. A timelapse’s final frame shows the most-built-up object, which reads best as
a poster.
Nonefor a Video (no frame file to serve — the caller extracts one with ffmpeg, seevideo_thumb_args). Pure. Frame indices are zero-padded, so the lexicographic max is the newest frame. - transcode_
args - ffmpeg argv to transcode a raw
plain.mjpeg(the fallback recorded when ffmpeg was absent at capture time) into a playable mp4 atout. Pure. - transcode_
mp4 - Transcode a raw mjpeg recording to mp4 (the thin ffmpeg seam). Same error mapping as
assemble_mp4. - video_
thumb_ args - ffmpeg argv to grab a single downscaled still from a video
inputintoout(a jpeg poster for a Video recording’s thumbnail). Seeks ~1s in to skip a black/opening frame. Pure, so the command shape is unit-tested without ffmpeg.