Repository navigation
Conversation
…he shown frame - A broadcast switch in the drawer (core/broadcast.ts broadcastToggle): a seated viewer turns it on and off; a late viewer sees it on and disabled with the coordinator's reason, and an offer to reload once a seat is free. - In broadcast mode the canvas streams nothing (no direct or aggregated sources, the plan suspended), no VM opens, there is no "Your own GPU"; words, lights, votes and "restart now" stay. ?broadcast=1 asks for it; the choice is remembered with the stream mode. - app/_wall/Broadcast.tsx plays the channel with the IVS web player 1.57.0 over the image, maps each frame's SEI (scene t and epoch) by media time to the frame requestVideoFrameCallback presents, and reloads after an error or the end of the stream, with the newest playback token. - The overlay is drawn from the snapshot in effect at the shown frame's wall time (the store keeps 30 s of snapshots with their coordinator arrival time when a broadcast is offered), and the page's "now" is that frame's time, so clocks and phases change with the picture. Lights are placed at the shown frame's t. The strip shows the broadcast's latency. - Direct frame URLs carry the admission's token (admit=); a renewed token does not reopen a running stream. A late viewer probes no address family. The tab keeps its seat ticket in sessionStorage and presents it on reconnect (/live?seat=). docs/fleet/ARCHITECTURE.md: inputs show in the video about one latency after the coordinator accepts them (the drawer's status line says so at once); ?broadcast=1. Tests (core/test/broadcast.test.ts): the history window, the snapshot in effect at a frame, the shown frame's advance and stall limit, the overlay state and "now" at the shown frame, who watches the broadcast, the toggle locked for a late viewer, no direct or aggregated source for a late viewer in any mode, VM controls gone and scene inputs kept, seated direct URLs with the token, token-only changes keeping a stream. pnpm lint, typecheck, 289 unit tests and 58 browser tests passed.
|
@codex review |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the
|
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4879a5c4d3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…use pauses it - The wake recording left when the canvas had every stream at one t, which never happens in broadcast mode (it streams nothing), so it stayed over the live broadcast. The view's "picture whole" is now the player having presented a frame in broadcast mode, for the recording and the LIVE badge. - The page's Pause reached only the canvas worker. The view now carries the pause to the player (broadcast.paused), which pauses and resumes the IVS player and starts paused when switched to while paused. core/test/broadcast.test.ts: lets the recording go once the broadcast presents a frame, and tells the player the page is paused; both failed before the change. pnpm lint, typecheck and 291 tests passed.
ejc3
left a comment
There was a problem hiding this comment.
NOT-A-DEFECT: Codex's review body carries no finding of its own; its inline findings are answered in their threads.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dc2ac97421
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const onPresented = (_now: number, md: VideoFrameCallbackMetadata) => { | ||
| const f = byTime.get(Math.round(md.mediaTime * 1000)); | ||
| if (f) onFrameRef.current({ ...f, at: performance.timeOrigin + md.expectedDisplayTime }); | ||
| callback = video.requestVideoFrameCallback(onPresented); |
There was a problem hiding this comment.
Match SEI metadata that arrives after frame presentation
When an SEI event arrives after its frame's presentation callback, this lookup misses and that frame is never matched again. The existing measurement harness explicitly handles this ordering with pending presentations (fleet/tools/ivsmeasure/player.html:37-47), but this player only stores the late metadata. Replaying both event orders against these handlers produces one onFrame call for metadata-first and zero for presentation-first. If metadata consistently arrives late, the overlay follows live state instead of the displayed video, and the recording cannot leave after wake because broadcast readiness remains unset. Retain pending presentations and match them when their SEI arrives.
Useful? React with 👍 / 👎.
| export function snapshotAt(h: readonly HistoryEntry[], wallMs: number): HistoryEntry | null { | ||
| let best: HistoryEntry | null = null; | ||
| for (const x of h) if (x.at <= wallMs && (best === null || x.at > best.at)) best = x; | ||
| return best ?? h[0] ?? null; |
There was a problem hiding this comment.
Preserve the overlay snapshot while its frame remains displayed
When playback is paused or stalled for longer than the 30-second history window, incoming snapshots evict the state corresponding to the displayed frame. This fallback then selects a newer snapshot even though the video has not advanced, so tile phase masks and race results change over a frozen picture. A reducer replay with the same ShownFrame changes a tile's overlay from running to restoring after a snapshot arrives 31 seconds later. Keep the snapshot associated with the displayed frame pinned until another frame is presented, independently of the rolling history.
Useful? React with 👍 / 👎.
Stacked on: feat/broadcast-admission (PR #1387)
The page side of broadcast mode (docs/fleet/ARCHITECTURE.md, "Broadcast mode").
Contract
?broadcast=1asks for broadcast mode.app/_wall/Broadcast.tsx): the IVS web player 1.57.0 on a<video>over the image. Each frame's SEI (scenet, epoche) is matched by media time to the framerequestVideoFrameCallbackpresents. After an error or the stream's end it reloads with the newest playback token.core/broadcast.ts): with a broadcast on offer the store keeps 30 s of snapshots with their coordinator arrival time. In broadcast mode the overlay is drawn from the snapshot in effect at the shown frame's wall timee + 1000 t, and the view's "now" is that frame's time, so clocks and phases change with the picture. Lights are placed at the shown frame'st. The strip shows the broadcast's latency.admit=); a renewed token does not reopen a running stream. A late viewer runs no address-family probe. The tab keeps its seat ticket in sessionStorage and presents it on reconnect.Downstream impact
Without an admission that offers a broadcast (no
--broadcast-listen), nothing changes: no toggle, no history kept. Renderers do not checkadmit=yet; enforcement is the next PR.Evidence
core/test/broadcast.test.ts(12 tests): the history window and versions; the snapshot in effect at a frame; the shown frame's advance and its stall limit; the overlay state and "now" at the shown frame, leaving the live state untouched; who watches; the toggle locked for a late viewer with its reason and reload offer; no direct or aggregated source for a late viewer in any mode, with the plan suspended; VM controls gone and scene inputs kept; seated direct URLs carrying the token; a token change keeping the same stream.pnpm lint,pnpm typecheck,pnpm test(289 passed),pnpm build,pnpm test:e2e(58 passed, chromium, webkit and screenshots).