Skip to content

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"