The TLS-handshake explanation for the 403 was wrong. The split is by token
form, not by client: Python fetches the master (query token) fine and fails
only on the media playlist (path token). That is why record_live.py mints a
master and why --downloader ffmpeg is required.
"The stream never ends" was one video observation stated as a rule, and an
audio stream has since contradicted it by terminating cleanly well inside the
cap. Both are now recorded as single observations rather than conclusions.
Also records the state of play: unattended recording works, login has never
been tested, and the decision not to automate it -- the cookie outlives a
quarter, so automating the riskiest step to save four manual logins a year is
a bad trade.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kyt7QHQvLJtQRuiY4wAqKB
The feed switches to a static league slate and keeps serving at full CBR
bitrate. No end marker, and no stall to detect, so neither of the obvious
exit conditions fires. The duration cap is the only stop condition.
Observed on a live match: 116 min recorded, still running 2h04m after
kickoff, stopped manually.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kyt7QHQvLJtQRuiY4wAqKB
Verified end to end against a live match: 1080p H.264/AAC MPEG-TS at
~5.2 Mbit/s, recorded while the browser played the same stream.
Components:
- tampermonkey sniffer hooks fetch/XHR at document-start, captures the
manifest URL verbatim and POSTs it to the local catcher. v0.4 also traces
the API chain to find which call mints the token.
- catcher receives the URL and launches yt-dlp. Dedupes on the Kaltura asset
id and checks downloader liveness, so a mid-match page reload is both safe
and the recovery path for a dead downloader.
- creds stores secrets in the OS vault rather than a gitignored file, and
refuses to run on a backend that does not encrypt.
Protocol notes are in the README: the stream uses a two-stage token chain
(a ~25s hdnts token for the master playlist, a ~24h hdntl token for media),
concurrency is unrestricted, and the live window is ~30s with no DVR.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kyt7QHQvLJtQRuiY4wAqKB