Old Bird

Settings reference

Every preference Old Bird exposes. The in-app screen, the web viewer, the HTTP API, and the boot receiver all read from the same SharedPreferences("oldbird_prefs"); changes apply live.

Categories

Access

Private networks onlyrestrict_to_privatedefault on

Reject requests from public IP addresses. The allowlist permits RFC 1918 (10/8, 172.16/12, 192.168/16), link-local (169.254/16), loopback, IPv6 ULA (fc00::/7) and RFC 6598 / Tailscale CGNAT (100.64.0.0/10). Applied before auth, so off-LAN clients never reach the password check.

Turn off only when fronting Old Bird with another auth layer (reverse proxy + mTLS, VPN gateway, etc).

Usernameauth_username

Always oldbird. Read-only display.

Passwordauth_password

Random 12-character string, generated on first service start and persisted on the device. Tap to reveal, tap again to copy.

Regenerate passwordregenerate_password

Replaces the current password with a fresh random value. Existing browser sessions immediately get a 401 and re-prompt.

Service

Streaming serviceservice_enableddefault off

Toggles the foreground service that hosts the camera, audio, HTTPS server and HTTP landing page. Honoured by BootReceiver: if this is on at boot and the CAMERA permission is granted, the service auto-starts.

Camera list previewspreviews_enableddefault on

Show a thumbnail next to each camera in the camera list. Off saves a small amount of memory on devices with several lenses.

LAN URLlocal_url

Read-only display of the discovered LAN address (https://<ip>:<port>). Updates when the service binds.

Share LAN connectionlocal_share

Sends URL + username + password to another device via the system share sheet.

HTTPS porthttps_portdefault 8443

Port for the encrypted viewer and all camera/audio/recording/RTSP-control endpoints. Range 1024–65535. Server rebinds when changed.

HTTP portportdefault 8080

Plain-HTTP port. Serves only the landing page that explains the self-signed-certificate warning and links into the HTTPS viewer. No camera endpoints.

Video

Rotationrotationdefault 0

Rotate the stream for sideways or upside-down mounts. Choices: 0° / 90° / 180° / 270°. Cross-axis rotations (0↔90, 180↔270) trigger an encoder hub rebuild because the dimensions swap; same-axis rotations are a metadata flip on the running session.

Resolutionresolutiondefault 640x480

Choices populated from the camera's reported sizes. Changing reconfigures the capture session on the same open device — no CameraDevice close+reopen.

JPEG qualityqualitydefault 18

Range 1..100. Affects the MJPEG path only. Default is intentionally low for 24/7 streaming over Wi-Fi; bump to 50–80 for higher fidelity at the cost of bandwidth.

H264 qualityh264_qualitydefault 50

Range 1..100. Drives the H.264 encoder bitrate used by RTSP and recording. Live update via the encoder's bitrate parameter; no session drop.

Exposureexposure_compensationdefault 0

Range -24..+24. Camera2 auto-exposure offset. Step is device-specific (typically 1/3 EV per unit). Negative darkens, positive brightens.

Max frame ratefps_maxdefault 0 (no cap)

Caps the camera's auto-FPS range. Lower values let the HAL use longer exposures in low light. Choices: 0 (no cap), 1, 5, 10, 15, 20, 24, 30 fps. Effective fps is always the lower of the user's cap and what the camera advertises.

Recording

Record to devicerecording_enableddefault off

Saves MP4 segments under Android/data/app.oldbird.webcam/files/Movies/. Camera and audio stay on whenever recording is active, regardless of viewer count.

Segment lengthrecording_segment_secondsdefault 1800 (30 min)

Choices: 1 m / 5 m / 15 m / 30 m / 1 h / single file. Rollover requests an IDR keyframe, closes the muxer, then opens a new one on the next keyframe.

Max files keptrecording_max_segmentsdefault 5

Ring buffer cap. The oldest finalised segment is deleted whenever a new one is finalised past this count.

WebDAV

Record to WebDAVwebdav_enableddefault off

Encodes another stream of MP4 segments and uploads each finalised file via HTTP PUT with Basic Auth. Three retries, exponential backoff. On success the local copy is deleted.

Wi-Fi onlywebdav_wifi_onlydefault on

Pause uploads on cellular; resume when Wi-Fi returns. Encoding still runs locally so no clip is lost.

Segment lengthwebdav_segment_secondsdefault 300 (5 min)

Independent of the on-device recording cadence. Shorter segments upload sooner; longer ones save server overhead.

URLwebdav_url

Directory URL ending in /, e.g. https://dav.example.com/oldbird/. Each segment is uploaded as <url><filename>.

Use https:// — plain http:// exposes Basic Auth credentials to anyone on the path.

Usernamewebdav_username

WebDAV account username for Basic Auth.

Passwordwebdav_password

WebDAV account password. Stored on the device only.

Keep failed uploadswebdav_max_failed_keptdefault 5

Permanent failures are renamed failed-upload-*.mp4 and kept up to this many. Oldest evicted past the cap.

Motion detection

Detect motionmotion_enableddefault off

Holds the camera alive at idle fps while continuously diffing frames. On detection it bumps fps, optionally records a clip, and fires the configured webhook.

Sensitivitymotion_sensitivitydefault 50

Range 1..100. One slider tunes both the per-cell luminance threshold and the minimum-cells-changed count together. Higher = trigger on smaller / fainter changes.

Idle frame ratemotion_idle_fpsdefault 2

Camera fps while waiting for motion. Lower keeps the device cooler; too low can miss fast events.

Post-rollmotion_post_roll_secondsdefault 15

Keep recording for this long after the last detection. Subsequent detections during this window extend the deadline.

Record on motionmotion_recorddefault on

Save each event as motion-<timestamp>.mp4 in the recordings folder. Independent of the regular Record to device setting; both can run side-by-side.

Alert providermotion_alert_providerdefault generic

Choices: generic, custom, ntfy, slack, discord, telegram. The settings UI shows / hides the fields below per provider; the JSON layer (/motion) advertises the same flags so the viewer can do the same.

See Integrations → Motion alerts for the wire format each provider produces.

Alert URLmotion_alert_url

Used by Generic / Custom / ntfy / Slack / Discord. For Slack and Discord the embedded webhook secret is the auth. For Telegram, leave blank — the URL is reconstructed from the bot token.

Alert Authorization headermotion_alert_auth

Verbatim Authorization header value, e.g. Bearer abc123 or Basic dXNlcjpwdw==. Used by Generic / Custom / ntfy. Leave blank for no auth.

Bot token (Telegram)motion_alert_token

Telegram bot token from @BotFather, looks like 123456789:ABCdef.... Used to build the https://api.telegram.org/bot<TOKEN>/sendMessage URL.

Chat ID (Telegram)motion_alert_chat_id

Numeric chat id (private chat or group) or @channelname for public channels. Find your numeric id by messaging your bot then opening https://api.telegram.org/bot<TOKEN>/getUpdates.

Body template (Custom)motion_alert_body_template

Template fired on motion. Placeholders: {camera}, {ip}, {time}, {timestamp}. Default (when blank): {"event":"motion","camera":"{camera}","ip":"{ip}","timestamp":{timestamp}}.

User-supplied templates use raw substitution — you own escaping for whatever format you target.

Content-Type (Custom)motion_alert_content_type

Override the request Content-Type header. Default: application/json; charset=utf-8. For form-encoded providers (Pushover, etc.): application/x-www-form-urlencoded.

Wi-Fi

Keep Wi-Fi awakewifi_keep_awakedefault on

Hold a Wi-Fi lock so the stream doesn't stall when the screen is off. Uses the low-latency mode on Android 10+ and the high-performance mode on older versions. Released only when the service is fully idle.

RTSP

RTSP serverrtsp_enableddefault off

Enables the RTSP/1.0 server. Same auth + IP allowlist + rate-limit pipeline as HTTP. URL is rtsp://oldbird:<password>@<phone-ip>:<port>/.

RTSP portrtsp_portdefault 8554

Range 1024–65535. Port change rebinds the listener and drops in-flight sessions.

Internet access

Access over the internetinternet_access_enableddefault off

Opens an SSH reverse tunnel to localhost.run so the camera is reachable outside the LAN. Requires a Google sign-in to register the URL with the viewer.

Google accountinternet_signin

Sign in to register this camera with your viewer. The registration is a Firestore document keyed by your Google UID.

End-to-end passphrasee2e_passphrase

Derives a per-user PBKDF2 key used to encrypt camera credentials before they transit Firestore. The verifier is stored under users/{uid}/profile/main; the passphrase itself never leaves the device.

Public URLinternet_url

Read-only display of the current localhost.run URL. Empty when the tunnel is idle.

Share connectioninternet_share

Sends the public URL plus credentials to another device via the system share sheet.

Camera namecamera_name

Human-readable label for this camera in the viewer registration. Also surfaces in motion alerts as the camera field.