This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
DashStack is an installable Python CLI tool that stacks front/rear dashcam clips vertically (front on top, rear on bottom) and concatenates them chronologically. It shells out to ffmpeg/ffprobe for all media processing. No external Python dependencies.
src/dashstack/cli.py— all CLI logic (entry point:main())src/dashstack/__init__.py— package versionpyproject.toml— packaging config, definesdashstackconsole script
- Python 3.9+
ffmpegandffprobeon PATH
pip install -e . # editable install for development
dashstack videos # run on a directory
dashstack --helpKey flow in src/dashstack/cli.py:
-
Discovery (
discover_pairs): Scans input dir for files matchingFILE_RE(*YYYYMMDD_HHMMSS_F.mp4/*_R.mp4) and groups them intoClipPairs by timestamp. Also scans for existing_FRfiles viaFR_RE; source clips whose timestamps fall within an_FRrange are suppressed (skipped). Returns(pairs, merged_clips, unmatched, overwritten). -
Probing (
ffprobe_clip): Callsffprobeto get resolution, fps, duration, and audio presence for each clip. Results are cached per-path. Probing runs in parallel when multiple clips exist. -
Auto-detection (
detect_video_codec,detect_hwaccel): Queries ffmpeg for available hardware encoders and decoders. Priority: (1) CUDA + NVENC → full GPU pipeline withscale_cuda, (2) multi-core CPU (>=4 cores) →libx264 ultrafastCRF with parallel segment workers, (3) other HW encoders. -
Mode selection (
_main):- Split mode (default, no
--output):split_into_runsgroups clips + merged_FRfiles into continuous runs separated by gaps >--gap-threshold. Each run produces one_FRoutput file in the input directory viarun_split_pipeline. - Single-file mode (
--output path.mp4): combines everything into one file.autopipeline chooses between single-pass and segment modes.
- Split mode (default, no
-
Pipeline types:
- single-pass: Feeds two concat-demuxer lists (all fronts, all rears) into one ffmpeg invocation. Used for non-GPU HW encoders or single-pair runs. Only supports
ClipPairs. - segment (
run_segment_pipeline): Handles mixedSegmentlists (ClipPair+MergedClip). Encodes eachClipPairindividually (in parallel via--workers), passesMergedClippaths through to the concat list without re-encoding, then concatenates with stream copy.
- single-pass: Feeds two concat-demuxer lists (all fronts, all rears) into one ffmpeg invocation. Used for non-GPU HW encoders or single-pair runs. Only supports
-
Encoding: Builds ffmpeg filter graphs and codec args. When CUDA + NVENC are available, uses
scale_cuda+hwdownload+ CPUvstackto keep decode/scale on GPU. Otherwise uses CPU filters (scale+pad+vstack). Supportslibx264(CRF mode) and hardware codecs. -
Filename fixing (
_fix_fr_names): On every run, automatically probes existing_FRfiles and renames any whose end timestamp is wrong or missing (computed as start + duration). -
Cleanup (
--clean): Deletes source_F/_Rfiles whose timestamps are covered by_FRfiles, and also deletes older_FRfiles that are fully subsumed by a larger_FRfile. -
Overlap trimming (
_compute_overlaps): When adjacent segments overlap in time, the earlier segment is truncated. ClipPairs use-tduring encoding; MergedClips use concat demuxerdurationdirectives. -
Dedup (
dashstack dedup): Post-hoc duplicate removal for already-merged videos. Extracts small grayscale thumbnails at 1fps, detects cut points (abrupt frame changes), then verifies if footage after each cut matches footage from before it. Removes duplicates via concat demuxerinpoint/outpointwith stream copy.
Key types: ClipPair (F+R source pair), MergedClip (existing _FR file with start/end timestamps), Segment = Union[ClipPair, MergedClip].
- Keep README.md updated when adding, changing, or removing user-facing features (new flags, subcommands, behavior changes). The README is the primary user documentation.