Configuration reference¶
Cang reads a single TOML file at startup. Pass the path via the CLI (see cang --help).
[server]¶
| Key | Type | Required | Default | Description |
|---|---|---|---|---|
output_dir |
string (path) | yes | — | Root directory for all cang output (clips, database, log). |
scan_interval |
integer | no | 300 |
Seconds between periodic re-scans of all camera roots. Acts as a fallback for files that the inotify watcher missed (e.g. bulk directory copies). On NFS mounts, inotify is unavailable and silent — scan_interval is then the only pickup mechanism; lower the value (e.g. 30) for faster response. Set to 0 to disable. |
retention_days |
integer | no | 30 |
How many days to keep motion snapshots before automatic deletion. |
background_retention_days |
integer | no | 14 |
How many days to keep background ([F] flag) snapshots before automatic deletion. |
video_retention_days |
integer | no | 7 |
How many days to keep transcoded video clips before automatic deletion. |
Storage layout¶
Everything cang produces lives under output_dir:
output_dir/
cang.db # metadata database
<camera>/
clips/<YYYY-MM-DD>/<date>-<start>-<end>.mp4 # transcoded clips
clips/<YYYY-MM-DD>/<date>-<start>-<end>.jpg # clip thumbnails
snapshots/<YYYY-MM-DD>/<HH.MM.SS>-….jpg # camera snapshots
Processed media is moved out of the camera incoming folders: after a clip
transcodes successfully its .dav/.mp4 source and .idx sidecar are
deleted, snapshots are moved on ingest, and emptied date/hour directories
are pruned. Anything still present in an incoming folder is unprocessed
(or failed — check ffmpeg.log).
Upgrading from earlier versions¶
On first startup cang migrates automatically: snapshots referenced by the
database move from the incoming folders into the store above, existing
clips and thumbnails move into clips/<date>/, and sources of
already-transcoded clips are removed from incoming. The migration only
ever deletes an incoming file after a verified copy exists in
output_dir; files not yet processed are untouched. The
delete_after_transcode option is gone — sources are always removed
after successful processing (a warning is logged if the key is still in
your config).
[[camera]]¶
One [[camera]] block per camera. At least one is expected.
| Key | Type | Required | Default | Description |
|---|---|---|---|---|
name |
string | yes | — | Human-readable label used in logs and the web UI. |
adapter |
string | yes | — | Folder-layout adapter. Currently only "dahua" is supported. |
root |
string (path) | yes | — | Root directory that the adapter scans for incoming clips. For the dahua adapter this must point directly at the camera's serial directory (e.g. /mnt/nvr/ABC123456); date subdirectories are expected immediately inside. |
[web]¶
All keys are optional. Omitting the section uses the defaults shown below.
| Key | Type | Default | Description |
|---|---|---|---|
host |
string | "0.0.0.0" |
Interface address for the HTTP server. |
port |
integer | 8080 |
TCP port for the HTTP server. |
username |
string | — | Login username. Must be set together with password. |
password |
string | — | Login password. Must be set together with username. |
If neither username nor password is set, the web UI is accessible without authentication.
Time synchronisation¶
Cang prunes empty snapshot source directories once their calendar day has passed. This relies on the server clock agreeing with the cameras' clocks — the server must know when "midnight" is in the same timezone the cameras name their date directories with. If the server and cameras disagree about the current date, pruning may delete directories the camera is still writing to, or leave finished directories unpruned.
All cameras must be in the same timezone as the server, and all clocks must be
kept accurate with NTP (Network Time Protocol). Container users should set the
TZ environment variable to the camera timezone (e.g. TZ=Australia/Brisbane).
Example¶
[server]
output_dir = "/var/lib/cang/clips"
scan_interval = 300 # periodic re-scan every 5 minutes (default)
# on NFS mounts inotify is unavailable — lower this (e.g. 30)
# for faster pickup when the camera root is on a network share
retention_days = 30 # keep motion snapshots for 30 days (default)
background_retention_days = 14 # keep background snapshots for 14 days (default)
video_retention_days = 7 # keep video clips for 7 days (default)
[web]
host = "0.0.0.0"
port = 8080
username = "admin"
password = "s3cr3t"
[[camera]]
name = "front-door"
adapter = "dahua"
root = "/mnt/nvr/ABC123456" # serial directory — date folders sit directly inside
[[camera]]
name = "back-yard"
adapter = "dahua"
root = "/mnt/nvr/DEF789012"