id = "dvr-scan" name = "DVR-Scan" homepage = "https://github.com/Breakthrough/DVR-Scan" description = "An open-source motion detection program for video files." executables = ["dvr-scan"] [dotfiles] # DVR-Scan's official configuration documentation lists the Linux, macOS, # and Windows user config locations below. [configHome] is the documented # XDG_CONFIG_HOME override on Linux. # https://github.com/Breakthrough/DVR-Scan/blob/main/dvr-scan.cfg paths = [ "~/.config/DVR-Scan/dvr-scan.cfg", "[configHome]/dvr-scan.cfg", "~/Library/Preferences/DVR-Scan/dvr-scan.cfg", "%LOCALAPPDATA%/DVR-Scan/dvr-scan.cfg", ] secret = [] [commands] format = 1 label = "Detect motion in video" description = "Scan one or more videos for motion events and save them. Regions, overlays, config files and time-range options are mostly left out." quality = "ai-draft" parser = { end_of_options = "--", interleave = "permute", long_equals = true, short_attached = false, short_bundles = false } [[commands.source]] id = "docs" kind = "manual" url = "https://www.dvr-scan.com/docs/" revision = "2026-10-27" evidence = """ * -i video.mp4, --input video.mp4 * -d path, --output-dir path * -m mode, --output-mode mode (opencv, encode, ffmpeg, copy) * -so, --scan-only * -t value, --threshold value * -l time, --min-event-length time * -tb time, --time-before-event time * -tp time, --time-post-event time * -st time, --start-time time * -et time, --end-time time * -df factor, --downscale-factor factor * -fs num_frames, --frame-skip num_frames * -b type, --bg-subtractor type (MOG2, CNT, MOG2_CUDA) * -bb, --bounding-box * -tc, --time-code * -q, --quiet * --report file """ [[commands.field]] id = "input" label = "Input video" description = "Repeat to scan several videos (not supported with the ffmpeg and copy output modes)." type = "path" option = ["--input", "-i"] multiple = true path = { kind = "file", role = "input", must_exist = true } sources = ["docs"] [[commands.field]] id = "output_dir" label = "Output directory" description = "Defaults to the working directory." type = "path" option = ["--output-dir", "-d"] path = { kind = "directory", role = "output", must_exist = false } sources = ["docs"] [[commands.field]] id = "output_mode" label = "Output mode" type = "enum" option = ["--output-mode", "-m"] choices = [{ value = "encode", label = "Encode (MP4, H.264)" }, { value = "opencv", label = "OpenCV (AVI)" }, { value = "ffmpeg", label = "ffmpeg" }, { value = "copy", label = "Copy streams" }] sources = ["docs"] [[commands.field]] id = "scan_only" label = "Scan only" description = "Detect and list events without saving video." type = "boolean" option = ["--scan-only", "-so"] sources = ["docs"] [[commands.field]] id = "threshold" label = "Threshold" description = "Lower values are more sensitive to motion." type = "number" option = ["--threshold", "-t"] sources = ["docs"] [[commands.field]] id = "min_event_length" label = "Minimum event length" type = "string" option = ["--min-event-length", "-l"] sources = ["docs"] [[commands.field]] id = "time_before" label = "Time before event" type = "string" option = ["--time-before-event", "-tb"] sources = ["docs"] [[commands.field]] id = "time_post" label = "Time after event" type = "string" option = ["--time-post-event", "-tp"] sources = ["docs"] [[commands.field]] id = "start_time" label = "Start time" description = "Timecode to start detection from, for example 00:35:52." type = "string" option = ["--start-time", "-st"] sources = ["docs"] [[commands.field]] id = "end_time" label = "End time" type = "string" option = ["--end-time", "-et"] sources = ["docs"] [[commands.field]] id = "downscale_factor" label = "Downscale factor" type = "integer" option = ["--downscale-factor", "-df"] sources = ["docs"] [[commands.field]] id = "frame_skip" label = "Frame skip" type = "integer" option = ["--frame-skip", "-fs"] sources = ["docs"] [[commands.field]] id = "bg_subtractor" label = "Background subtractor" type = "enum" option = ["--bg-subtractor", "-b"] choices = [{ value = "MOG2", label = "MOG2" }, { value = "CNT", label = "CNT" }, { value = "MOG2_CUDA", label = "MOG2 (CUDA)" }] sources = ["docs"] [[commands.field]] id = "bounding_box" label = "Draw bounding box" type = "boolean" option = ["--bounding-box", "-bb"] sources = ["docs"] [[commands.field]] id = "time_code" label = "Draw time code" type = "boolean" option = ["--time-code", "-tc"] sources = ["docs"] [[commands.field]] id = "report" label = "Event report file" description = "A .csv or .json file listing the detected events." type = "path" option = ["--report"] path = { kind = "file", role = "output", must_exist = false } effect = "overwrite" sources = ["docs"] [[commands.field]] id = "quiet" label = "Quiet" type = "boolean" option = ["--quiet", "-q"] sources = ["docs"] [[commands.task]] id = "extract" label = "Extract motion events" fields = ["input", "output_dir", "output_mode"] required = ["input"] [[commands.task]] id = "scan" label = "Scan and report only" fields = ["input", "scan_only", "report"] required = ["input", "scan_only"] set = { scan_only = [true] } [[commands.group]] id = "basic" label = "Basic" fields = ["input", "output_dir", "output_mode", "scan_only", "threshold", "report"] [[commands.group]] id = "advanced" label = "Advanced" fields = ["min_event_length", "time_before", "time_post", "start_time", "end_time", "downscale_factor", "frame_skip", "bg_subtractor", "bounding_box", "time_code", "quiet"]