mostlyright.weather.earnings.capture.live_hls
mostlyright.weather.earnings.capture.live_hls
Section titled “mostlyright.weather.earnings.capture.live_hls”Live-HLS rolling-window capturer (Phase 27, 27-09 Wave 5).
The live-during-broadcast tap. Where the 27-03 VOD path cold-fetches a FINISHED
static progressive MP4 (static.events.q4inc.com/.../{uuid}.mp4, which does not
exist yet mid-call), THIS producer follows a call in progress at the live edge of
an HLS media playlist that has NO #EXT-X-ENDLIST and yields (pcm_frame, spoken_at) tuples into the streaming STT (27-10).
Mechanics (27-RESEARCH-LIVE-STREAMING §1):
- Resolve the provider’s multivariant MASTER (Q4/IVS =
playback.live-video.net, discovered via the 27-03 guest flow) and_select_audio_only()picks theaudio_onlyrendition (mp4a.40.2, 48 kHz mono — NO video pull/decode).- Re-pull that media playlist every ~“targetDuration“, diff by
#EXT-X-MEDIA-SEQUENCE(a high-watermark), fetch ONLY newly-appeared segments (exactly-once), decode each to PCM, and yield(frame, spoken_at).- On a media/segment 403 or in-URL-token TTL expiry,
_refresh_media_url()RE-FETCHES the OPEN master (200 cold, no auth — NKE-validated) to mint a fresh in-URL media token; capture resumes without a gap.- Terminate on
#EXT-X-ENDLIST(clean end-of-stream) OR a no-new-segment stall (dropped/ended stream). RaiseLiveEdgeFellBehindif the rolling window evicts an unfetched segment (keep-up failure is LOUD, never a silent gap — T-27-32).
Legal (D-27.9): audio is a TRANSIENT frame stream into STT — NEVER written to
disk, NEVER a parquet column, NEVER served. The capturer yields decoded PCM bytes
in-memory; nothing touches the filesystem. session_headers are OPTIONAL — Q4/IVS
needs none (master + media + segments are 200 cold, token in-URL); header-gated
providers (ChorusCall / webcasts.com) pass Origin/Referer/UA.
Live PROOF is out-of-band. The unit tests drive SYNTHETIC rolling-window fixtures (no live network). The live-edge posture is proven by 27-09 Task 1’s operator-gated spike + the NKE live-call validation (27-RESEARCH “Live-Path Validation”) — you cannot fabricate a real live edge in a headless test.
Classes
Section titled “Classes”ChorusCallLiveCapture() | ChorusCall live-HLS capture — a HEADER-GATED provider. |
|---|---|
LiveHlsCapturer(master_url, *[, …]) | Follows an HLS live edge and yields (pcm_frame, spoken_at) tuples. |
Q4LiveCapture() | Q4/IVS live-during-call capture — Amazon IVS playback.live-video.net. |
Exceptions
Section titled “Exceptions”LiveEdgeFellBehind([message, error_code, …]) | The rolling live window evicted a segment before it could be fetched. |
|---|---|
LiveManifestError([message, error_code, …]) | A live master/media playlist is malformed or missing the audio rendition. |
LiveSsrfRejected([message, error_code, …]) | A live master/media/segment URL failed the SSRF host allow-list (D-27.9). |
class mostlyright.weather.earnings.capture.live_hls.ChorusCallLiveCapture
Section titled “class mostlyright.weather.earnings.capture.live_hls.ChorusCallLiveCapture”Bases: CaptureAdapter
ChorusCall live-HLS capture — a HEADER-GATED provider.
Unlike Q4/IVS, ChorusCall’s live edge is header-gated (Origin/Referer/UA), so
live passes the guest-path session headers through to the
LiveHlsCapturer. The live-edge GO/NO-GO is the operator-gated 27-09
Task 1 spike (Q4/IVS is already banked GO; ChorusCall is DEFERRED to a real
scheduled call).
capture(event, **kwargs)
Section titled “capture(event, **kwargs)”Capture event to a transient AudioArtifact.
MUST stay on the public path (no auth/DRM/captcha circumvention — D-27.9)
and MUST return an artifact whose backing file is transient. Raise
CaptureNotAvailable when the
provider template exposes no cold-fetchable HTTP media (e.g. a dial-in
bridge) rather than emitting empty audio.
detect(url)
Section titled “detect(url)”Return True iff this adapter handles url’s webcast provider.
live(manifest_url, session=None)
Section titled “live(manifest_url, session=None)”Open a LiveHlsCapturer replaying the header-gated session.
exception mostlyright.weather.earnings.capture.live_hls.LiveEdgeFellBehind(message=”, , error_code=None, source=None, request_id=None)
Section titled “exception mostlyright.weather.earnings.capture.live_hls.LiveEdgeFellBehind(message=”, , error_code=None, source=None, request_id=None)”Bases: EarningsError
The rolling live window evicted a segment before it could be fetched.
ENGINE-LOCAL (subclasses EarningsError; NOT added to packages/core
— the live seam never touches the parity surface). Raised when the lowest
#EXT-X-MEDIA-SEQUENCE in a re-pulled manifest is greater than
watermark + 1 — i.e. a segment the capturer had NOT yet fetched aged out of
the rolling window. A silently-dropped segment would create an UNDETECTED
transcript gap (a wrong mention count), so keep-up loss must fail LOUD, never
leave a silent hole (threat T-27-32).
- Parameters:
- Return type: None
default_error_code : str = ‘EARNINGS_LIVE_EDGE_FELL_BEHIND’
Section titled “default_error_code : str = ‘EARNINGS_LIVE_EDGE_FELL_BEHIND’”Subclass override — the stable string enum surfaced via error_code.
error_code : str
Section titled “error_code : str”message : str
Section titled “message : str”request_id : str | None
Section titled “request_id : str | None”source : str | None
Section titled “source : str | None”class mostlyright.weather.earnings.capture.live_hls.LiveHlsCapturer(master_url, , session_headers=(), client=None, transport=None, poll_interval_s=None, max_stall_polls=6)
Section titled “class mostlyright.weather.earnings.capture.live_hls.LiveHlsCapturer(master_url, , session_headers=(), client=None, transport=None, poll_interval_s=None, max_stall_polls=6)”Bases: object
Follows an HLS live edge and yields (pcm_frame, spoken_at) tuples.
master_url is the multivariant MASTER (openly cold-fetchable for Q4/IVS).
session_headers is an OPTIONAL iterable of (name, value) pairs replayed
on every fetch — default empty (Q4/IVS needs none); header-gated providers
(ChorusCall / webcasts.com) pass Origin/Referer/UA. client is an injected
httpx.Client (tests pass one wrapping a MockTransport); when omitted a
fresh UA-only client is built and owned. poll_interval_s overrides the
manifest #EXT-X-TARGETDURATION re-pull cadence (tests pass 0.0).
max_stall_polls bounds a no-new-segment stall before clean termination.
- Parameters:
frames()
Section titled “frames()”Yield (pcm_frame, spoken_at) following the live edge exactly-once.
Resolves the audio_only media URL off the master, then loops: fetch the
media playlist, diff new segments by #EXT-X-MEDIA-SEQUENCE, fetch each
NEW segment exactly once, decode to PCM in-memory, and yield it with a
monotonic spoken_at derived from segment ordering x duration off the
session start. On a media/segment 403 the media URL is refreshed off the
OPEN master. Terminates on #EXT-X-ENDLIST or a no-new-segment stall;
raises LiveEdgeFellBehind on window-eviction keep-up loss. NO audio
is ever written to disk.
exception mostlyright.weather.earnings.capture.live_hls.LiveManifestError(message=”, , error_code=None, source=None, request_id=None)
Section titled “exception mostlyright.weather.earnings.capture.live_hls.LiveManifestError(message=”, , error_code=None, source=None, request_id=None)”Bases: EarningsError
A live master/media playlist is malformed or missing the audio rendition.
ENGINE-LOCAL. Raised by LiveHlsCapturer._select_audio_only() when the
multivariant master exposes no audio_only rendition (nothing to follow
without pulling video), or when a manifest cannot be parsed.
- Parameters:
- Return type: None
default_error_code : str = ‘EARNINGS_LIVE_MANIFEST_ERROR’
Section titled “default_error_code : str = ‘EARNINGS_LIVE_MANIFEST_ERROR’”Subclass override — the stable string enum surfaced via error_code.
error_code : str
Section titled “error_code : str”message : str
Section titled “message : str”request_id : str | None
Section titled “request_id : str | None”source : str | None
Section titled “source : str | None”exception mostlyright.weather.earnings.capture.live_hls.LiveSsrfRejected(message=”, , error_code=None, source=None, request_id=None)
Section titled “exception mostlyright.weather.earnings.capture.live_hls.LiveSsrfRejected(message=”, , error_code=None, source=None, request_id=None)”Bases: EarningsError
A live master/media/segment URL failed the SSRF host allow-list (D-27.9).
ENGINE-LOCAL (subclasses EarningsError; NOT added to packages/core
— the live seam never touches the parity surface). Mirrors the VOD path’s
q4._validate_media_url() guard: the live capturer fetches master_url
(caller-supplied from external calendar/event data), the media URL, and EVERY
segment URL — and both LiveHlsCapturer._select_audio_only() and
LiveHlsCapturer._new_segments() urljoin a line off a FETCHED manifest,
which honors an ABSOLUTE URL embedded in that (poisonable / MITM’able) manifest.
A poisoned #EXT-X-STREAM-INF / #EXTINF line pointing at
http://169.254.169.254/... (cloud metadata), file://, or an arbitrary
internal host would otherwise be GET’d verbatim from the exact ingest host
D-27.9 protects. Every fetch target is re-validated (https + provider host)
BEFORE the network is touched; a rejection raises this control signal.
- Parameters:
- Return type: None
default_error_code : str = ‘EARNINGS_LIVE_SSRF_REJECTED’
Section titled “default_error_code : str = ‘EARNINGS_LIVE_SSRF_REJECTED’”Subclass override — the stable string enum surfaced via error_code.
class mostlyright.weather.earnings.capture.live_hls.Q4LiveCapture
Section titled “class mostlyright.weather.earnings.capture.live_hls.Q4LiveCapture”Bases: CaptureAdapter
Q4/IVS live-during-call capture — Amazon IVS playback.live-video.net.
The LIVE edge is the IVS multivariant master (discovered from the live player
page via the 27-03 guest flow), NOT the VOD static.events.q4inc.com/*.mp4
(which does not exist mid-call). Needs NO session headers — master/media/
segments are 200 cold, the token is in-URL (NKE-validated). capture /
detect delegate to the VOD adapter’s contract shape; live opens a
LiveHlsCapturer.
capture(event, **kwargs)
Section titled “capture(event, **kwargs)”Capture event to a transient AudioArtifact.
MUST stay on the public path (no auth/DRM/captcha circumvention — D-27.9)
and MUST return an artifact whose backing file is transient. Raise
CaptureNotAvailable when the
provider template exposes no cold-fetchable HTTP media (e.g. a dial-in
bridge) rather than emitting empty audio.
detect(url)
Section titled “detect(url)”Return True iff this adapter handles url’s webcast provider.
live(manifest_url, session=None)
Section titled “live(manifest_url, session=None)”Open a LiveHlsCapturer on the IVS master (NO session headers).