Live portal: Go Live — browser window capture published over WHIP as <user>/HelmetCam-<date>; dumpd /me/stream-key
Go Live closes viewer windows, fetches the Authentik-identified user's MediaMTX key from dumpd (/etc/vanguard/streamers.json written by configure.py), opens Chrome's window-only picker with audio, prefers H.264 so MediaMTX can record, caps at 12 Mbps / 1440p60, shows live stats, Stop. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
19
bin/dumpd.py
19
bin/dumpd.py
@@ -19,6 +19,8 @@ SRC_DIRS = [ROOT / "streams", ROOT / "clips"]
|
||||
TRASH = ROOT / "trash"
|
||||
MARK = ROOT / ".markers"
|
||||
USERS_FILE = Path(os.environ.get("DUMP_USERS", "/etc/vanguard/dump-users.txt"))
|
||||
STREAMERS_FILE = Path(os.environ.get("STREAMERS_FILE", "/etc/vanguard/streamers.json")) # {"techy": "pass", ...} written by configure.py
|
||||
AUTH_USER_HEADER = os.environ.get("AUTH_USER_HEADER", "X-Authentik-Username")
|
||||
LISTEN = ("127.0.0.1", 8080)
|
||||
TZ = ZoneInfo(os.environ.get("DUMP_TZ", "America/New_York"))
|
||||
NIGHT_START = time(17, 0) # 5 pm
|
||||
@@ -92,6 +94,12 @@ def do_move(files, night):
|
||||
d.rmdir()
|
||||
return moved, size
|
||||
|
||||
def load_streamers():
|
||||
try:
|
||||
return json.loads(STREAMERS_FILE.read_text())
|
||||
except (OSError, json.JSONDecodeError):
|
||||
return {}
|
||||
|
||||
class H(BaseHTTPRequestHandler):
|
||||
server_version = "dumpd/1"
|
||||
def _json(self, code, obj):
|
||||
@@ -129,6 +137,17 @@ class H(BaseHTTPRequestHandler):
|
||||
return req_user or "all"
|
||||
return auth_user
|
||||
def do_GET(self):
|
||||
if self.path.startswith("/me/stream-key"):
|
||||
# Only reachable through Caddy behind Authentik forward-auth, which injects the username header.
|
||||
# dumpd binds to loopback, so a request carrying this header is one Caddy already authenticated.
|
||||
who = (self.headers.get(AUTH_USER_HEADER) or "").strip().lower()
|
||||
if not who:
|
||||
return self._json(401, {"error": "not authenticated"})
|
||||
streamers = load_streamers()
|
||||
pw = streamers.get(who)
|
||||
if not pw:
|
||||
return self._json(403, {"error": f"no stream key for '{who}' — ask the admin to add you as a streamer with that exact name"})
|
||||
return self._json(200, {"user": who, "pass": pw})
|
||||
if not self.path.startswith("/dump"):
|
||||
return self._json(404, {"error": "not found"})
|
||||
u = check_auth(self.headers.get("Authorization"))
|
||||
|
||||
Reference in New Issue
Block a user