3 KiB
3 KiB
zoitestream
Landing page + lightweight API for stream.dumpnet.chat, backed by
MediaMTX.
This is intentionally tiny: a single Flask process with a SQLite database
(on a persistent volume, not container-local disk) tracking the currently
active stream and stream history. MediaMTX calls this service's /hooks/*
endpoints on stream start/stop (via its runOnReady/runOnNotReady path
hooks), and the landing page polls /api/active and /api/history to
render status. An IRC bot can call /api/creds to fetch the current
publish URL to hand out to whoever wants to stream.
State persists across pod restarts/redeploys (SQLite file lives on the
shared appdata hostPath PV, mounted at STATE_DB_PATH).
Design notes
- One shared publish stream/password for everyone (a deliberate feature,
not a limitation) — credentials are retrievable via
/api/creds(meant for the IRC bot to call), never shown on the public landing page. The IRC channel is a high-trust environment, so this endpoint is only lightly protected (shared token), not treated as a hard secret boundary. /hooks/readyand/hooks/not-readyare protected by a separate shared token (HOOK_TOKEN) so MediaMTX is the only thing that can flip stream status — rotatable independently of the creds token.- Publish password itself lives in MediaMTX's own internal auth config
(
authInternalUsers), not validated by zoitestream — zoitestream just knows the current value (viaPUBLISH_PASSWORDenv var, sourced from the same secret) so it can hand it back out through/api/creds. - No scheduling API yet — planned as a future addition, likely driven by an IRC bot, and will live in the same SQLite database.
Endpoints
GET /— landing pageGET /api/active— JSON list of currently active streamsGET /api/history— JSON list of recent streams (capped, most-recent-first)GET /api/creds— publish URL/user/password (token-protected viaCREDS_TOKEN)GET /health— health checkPOST /hooks/ready— called by MediaMTXrunOnReady(form/query:path,source_type)POST /hooks/not-ready— called by MediaMTXrunOnNotReady(form/query:path)
Env vars
HOOK_TOKEN— shared secret required (as?token=orX-Hook-Tokenheader) on/hooks/*CREDS_TOKEN— shared secret required (as?token=orX-Creds-Tokenheader) on/api/credsPUBLISH_USER— publish username to report via/api/creds(defaultstreamer)PUBLISH_PASSWORD— publish password to report via/api/creds— must match MediaMTX's own configDOMAIN— display domain shown on the landing page and in/api/creds(defaultstream.dumpnet.chat)RTMP_PORT— RTMP port used in the URL built by/api/creds(default1935)STATE_DB_PATH— path to the SQLite file (default/data/zoitestream.db)HISTORY_LIMIT— number of history entries to retain (default50)
Local dev
uv sync
STATE_DB_PATH=./dev.db uv run flask --app wsgi:app run --debug