You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
TL;DR Switchframe is configured through three layers: command-line flags, environment variables, and on-disk state files. Flag parsing lives in parseConfig in a single file; environment variables are mostly flag overrides (SWITCHFRAME_*) plus a few low-level runtime knobs (GOGC, GOMEMLIMIT, METAL_LIBRARY_PATH, SWITCHFRAME_PROFILING). State directories default to ~/.switchframe/ and hold JSON stores for presets, macros, operators, SRT sources, clips, playout caches, and more — see file-formats.md for schemas. Build tags change what compiles: cgo, cuda, darwin, mxl, openh264, embed_ui, whisper, tensorrt.
The story
Switchframe's configuration surface is layered from most volatile to most durable. Command-line flags are the right place for everything that changes between runs — which port to listen on, which cameras to expose as sources in demo mode, which GPU model file to load. Environment variables are the right place for secrets and for flag values that operations tooling wants to inject without parsing CLI (API tokens, invite codes, engine labels). State files are the right place for things the operator creates at runtime and expects to persist across restarts (presets they saved, SRT sources they configured, clips they uploaded).
When a flag and an env var both control the same setting, flags take precedence when non-empty — see resolveEnvOrFlag. A small set of auto-generation fallbacks exist: if --api-token is not provided and SWITCHFRAME_API_TOKEN is not set, a fresh token is generated and printed on stdout at startup.
Build tags gate whole subsystems. Without the cgo tag, the binary compiles pure-Go stubs for FFmpeg, FDK-AAC, Opus, CUDA, Metal, and MXL — useful for cross-compilation and CI smoke tests, useless for production. The cuda tag pulls in NVENC/NVDEC; darwin tag pulls in Metal; mxl tag pulls in the MXL SDK; embed_ui tag embeds the SvelteKit UI into the binary via go:embed. Tests under //go:build correctness are the correctness test suite, separate from the normal go test ./....
The table format below lists every flag, env var, and build tag the code actually reads. Grep the source if you need the definition line; all flag definitions are in parseConfig unless noted otherwise.
Command-line flags
All flags are defined in parseConfig. Defaults reflect the source as of this doc.
Core server
Flag
Type
Default
Description
--addr
string
:8080
QUIC/HTTP3 listen address
--http-fallback
bool
false
Start a plain HTTP/1.1 API server for curl/scripts
Demo mode disables API auth.--demo causes initInfra to install a no-op auth middleware. Never run --demo on a public-reachable address.
Auto-generated API tokens print to stdout, not stderr. The token is printed once at startup to stdout so operators can capture it without log routing capturing it. Pipe stderr but preserve stdout.
--engine-label only accepts "", "a", or "b". Any other value is rejected at startup. This prevents silent split-brain from typos.
Flag precedence is flag → env → default. An empty flag value uses the env var; a set flag wins even if the env var is also set. resolveEnvOrFlag encodes this.
Auto-enabled in demo mode:--srt-listen (:6464), --playout, --scte35. These are set if unset when --demo is true.
Build tag combinations are additive. You cannot build cuda,darwin simultaneously (the files are mutually exclusive). Cross-compilation paths: on macOS, build Linux binaries via a container (see the Dockerfile and Dockerfile.cuda).
GOGC=400 is the default. Lower than 400 (more frequent GC) will cause frame-drop bursts; higher than 400 (less frequent GC) can exceed GOMEMLIMIT. Change only with a benchmark.
MXL discovery mode is a clean-exit flag.--mxl-discover lists available MXL flows on stdout and exits zero. It is not a server mode.
--warm-cache is an AMI build hook. It pre-generates ST map LUTs and exits. Do not use it in production runs.
The cert-hash endpoint is always unauthenticated. Browsers use it to bootstrap WebTransport with self-signed certs; authentication would block the UI from loading.