docs: Static Buffet 2.0 modernization PRD#7
Conversation
Repo audit + 2026 VJ landscape research distilled into a product plan: demolish customization bloat, build a WebGL2 two-deck compositor with ISF effects and a beat-clock, one dark performance UI, and sharpened Archive.org crate-digging ergonomics. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive Product Requirements Document (PRD) for Static Buffet 2.0, outlining a modernization plan that includes building a WebGL2 compositor, simplifying the UI to a single dark performance interface, and removing legacy features and unused dependencies. The reviewer provided a crucial technical correction regarding the limitations of transferring a MediaStream via BroadcastChannel, suggesting a direct same-origin window reference instead to successfully display the stream in the pop-out window.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
|
||
| ### 5.4 The signal (output done right) | ||
|
|
||
| - **Render once.** The compositor renders one canvas; the pop-out window receives `canvas.captureStream(60)`. `BroadcastChannel` replaces the postMessage/localStorage sync (`PopOutPlayer.tsx:327–631`). No more two players pretending to agree. |
There was a problem hiding this comment.
While using BroadcastChannel is excellent for syncing playback controls and state between windows, please note that a MediaStream (returned by canvas.captureStream()) cannot be serialized or transferred via BroadcastChannel or postMessage due to structured clone limitations.\n\nTo display the stream in the pop-out window, the parent window must directly assign the stream to the pop-out window's video/canvas element via the same-origin window reference (e.g., popoutWindow.document.getElementById('output').srcObject = stream). This requires the pop-out window to remain same-origin and be opened via window.open so the parent retains a direct reference.
| - **Render once.** The compositor renders one canvas; the pop-out window receives `canvas.captureStream(60)`. `BroadcastChannel` replaces the postMessage/localStorage sync (`PopOutPlayer.tsx:327–631`). No more two players pretending to agree. | |
| - **Render once.** The compositor renders one canvas; the pop-out window receives the canvas captureStream(60) via direct same-origin window reference. BroadcastChannel replaces the postMessage/localStorage sync for control state (PopOutPlayer.tsx:327-631). No more two players pretending to agree. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 713608460d
ℹ️ 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".
| - **Render once.** The compositor renders one canvas; the pop-out window receives `canvas.captureStream(60)`. `BroadcastChannel` replaces the postMessage/localStorage sync (`PopOutPlayer.tsx:327–631`). No more two players pretending to agree. | ||
| - **One-click projector fullscreen** via the Window Management API (`getScreenDetails`) on the second display. | ||
| - **Record my set**: `MediaRecorder` on the output stream → downloadable video. Every session becomes shareable content — this is how tools like this spread. |
There was a problem hiding this comment.
Preserve audio in the captured output stream
canvas.captureStream(60) supplies only the canvas video track, while the deck audio is produced separately from the hidden video/audio graph. Consequently, any set with audio will produce a silent pop-out and silent MediaRecorder download under this design. Mix the deck/beat audio into a MediaStreamAudioDestinationNode and add its audio track to the captured canvas stream before using it for output or recording.
Useful? React with 👍 / 👎.
What
Adds
PRD.md— a full product requirements document for modernizing Static Buffet from its current state ("feels like 2003") to a 2026-grade browser VJ instrument. Docs only; no code changes.Why
The current app's dated feel has three architectural root causes, all evidenced in the doc with file:line references:
<video>; the queue's "crossfade" field is exported but never actually performed (no A/B mixing exists).The PRD distills research across the 2026 VJ landscape (Resolume 7.27, VDMX6, Synesthesia, Noisedeck, LumaDeck, Radiance, ISF, Hydra/Butterchurn; ~60 sources in Appendix B) into a phased plan:
captureStreamoutput + set recordingReviewer notes
🤖 Generated with Claude Code