New Capability: Green Room Guest Experience
Date: 2026-04-07 Origin: Chris developed a prompt with Gemini for replacing VDO.ninja with a custom WebRTC guest ingestion system. V and Marquee assessed the architecture, planned and built the entire system in a single session. Impact: Show guests experience a branded, end-to-end journey — from pre-show preparation through live broadcast to personalized souvenir — on a single URL that transforms as the show progresses. VDO.ninja is completely eliminated from the production stack.
What Was Built
The Green Room is a self-hosted WebRTC guest ingestion system that replaces VDO.ninja across the entire Broadcast Studio. Guests open valuefirstteam.com/live/greenroom/{token} and experience a single surface that guides them through camera/mic setup, introduces them to other participants via mesh video, shows episode context, and then transforms seamlessly when the show goes live and again when it ends.
The system consists of four layers: a Socket.io signaling server on Fly.io that relays WebRTC handshakes, OBS feed pages on localhost that receive guest video for broadcast, a Director Dashboard integration that manages guest status and token generation, and a mutual-video mesh that lets the host and guests see and talk to each other before going live.
After the show, the same page transforms into a souvenir experience — the "ride photo" model. An automated pipeline extracts the guest's highlight clip (AI-selected, ffmpeg-cut, Mux-hosted), pulls their best quotes from the transcript, generates branded Tron:Ares quote cards, drafts LinkedIn social copy, and renders everything on the same URL. The guest shares from the link they already have.
Infrastructure Changes
| Change | Before | After |
|---|---|---|
| Guest ingestion | VDO.ninja (third-party, unbranded) | Self-hosted WebRTC at valuefirstteam.com/live/greenroom/{token} |
| Guest → OBS video | VDO.ninja view URLs in browser sources | localhost:3333/greenroom/feed/{1-4} |
| Screen share | VDO.ninja screen share URLs | localhost:3333/greenroom/feed/screen with dedicated WebRTC connection |
| Guest link generation | Manual VDO.ninja URL construction | HMAC-signed tokens generated from Director Dashboard |
| Pre-show guest communication | Separate VDO.ninja director window, back-channel messaging | Mutual video mesh in Green Room (host page + guest page) |
| Guest experience branding | VDO.ninja generic UI | Tron:Ares branded single-surface with show accent colors |
| Show lifecycle signals | None | Director emits show:started / show:ended via signaling |
| Production metadata | Not captured | Event log with timestamps, scene switches, guest slots written to D:/Recordings/ |
| Post-show guest assets | None (manual Canva if at all) | Automated souvenir pipeline: clip + quotes + visuals + social copy |
| Signaling infrastructure | None | Fly.io (vft-greenroom-signal.fly.dev), Metered.ca TURN relay |
| VDO.ninja references | Throughout broadcast/ (all scripts, presets, templates, docs) | Zero matches across entire broadcast directory |
Implementation
| File | Purpose |
|---|---|
broadcast/signaling/server.js |
Socket.io signaling server (deployed to Fly.io) |
broadcast/signaling/fly.toml + Dockerfile |
Fly.io deployment config |
broadcast/greenroom/guest-token.js |
HMAC-SHA256 token generation/validation (24h live + 365d souvenir) |
broadcast/greenroom/feed.html + feed.js |
OBS camera feed pages (WebRTC receive, slots 1-4) |
broadcast/greenroom/feed-screen.html + feed-screen.js |
OBS screen share feed page |
broadcast/greenroom/host.html + host.js |
Host mutual-video page (audio-only, sees all guests) |
apps/website/src/pages/live/greenroom/[token].astro |
Guest page — 3-phase surface (preshow/live/postshow) |
apps/website/public/greenroom/greenroom-guest.js |
Guest client logic — WebRTC, mesh, phases, souvenir |
broadcast/director/index.html |
Director Dashboard — guest cards, signaling, metadata capture |
broadcast/director/server.js |
Token API, feed routing, metadata endpoint, greenroom serving |
broadcast/director/show-presets.json |
guestId format (replaces pushId), room fields removed |
broadcast/scripts/souvenir-clip.js |
AI highlight selection + ffmpeg extraction + Mux upload |
broadcast/scripts/souvenir-quotes.js |
AI quote extraction + LinkedIn social copy generation |
broadcast/scripts/souvenir-visuals.js |
Tron:Ares quote card generation + thumbnail extraction |
broadcast/scripts/souvenir-pipeline.js |
Orchestrator — parallel execution, Sanity write, idempotent |
broadcast/scripts/vft-guest.ts |
CLI guest link generator (rewritten for Green Room tokens) |
broadcast/specs/greenroom-webrtc-implementation-spec.md |
Technical specification |
broadcast/director/AUDIT-2026-04-07.md |
Mirror visual QA audit results |
docs/plans/greenroom-webrtc-5p-plan.md |
Original WebRTC 5P plan |
docs/plans/greenroom-webrtc-prd.md |
Original WebRTC PRD |
docs/plans/souvenir-package-5p-plan.md |
Full guest experience 5P plan (expanded) |
docs/plans/souvenir-package-prd.md |
Full guest experience PRD (expanded) |
Usage
Generate a guest link (Director Dashboard)
- Open Director Dashboard at
http://localhost:3333 - Select show from timeline
- Click "Link" on any guest card → Green Room URL copied to clipboard
- Send URL to guest
Generate a guest link (CLI)
npx tsx broadcast/scripts/vft-guest.ts create --show=vfaidaily --guest="Nico Lafakis"
Open Green Room as host
Click "GREEN ROOM" button in Director Dashboard bottom bar, or navigate to:
http://localhost:3333/greenroom/host?show={showSlug}
Run souvenir pipeline after a show
node broadcast/scripts/souvenir-pipeline.js --show=vfaidaily --date=2026-04-07
Or with dry run: --dry-run
Deploy signaling server
export PATH="/home/coach_chris/.fly/bin:$PATH"
export FLY_API_TOKEN="$(grep FLY_API_TOKEN .env | cut -d= -f2- | tr -d '\r')"
cd broadcast/signaling && flyctl deploy
Restart Director server
lsof -ti:3333 | xargs kill 2>/dev/null
nohup node broadcast/director/server.js > /tmp/director-server.log 2>&1 &
Leader Applications
V (Operations)
Primary owner. V coordinates the Green Room lifecycle across shows: /show-prep writes episode context to Sanity, Director captures metadata during broadcast, /media-recap triggers the souvenir pipeline post-show. The production metadata capture (event log) feeds into V's daily operational briefing as a data source for show quality metrics.
Sage (Customer)
The Green Room is a relationship touchpoint. Sage's guest journey concierge (Usher) owns the end-to-end experience: pre-show link delivery, post-show souvenir notification. The souvenir's social copy is a distribution channel — every guest who shares amplifies the episode's reach through their network. Sage's signal recognition framework can detect when guests reshare souvenir content as an engagement signal.
Pax (Finance)
The souvenir pipeline replaces what would have been manual asset creation (Canva quote cards, manual clip editing, hand-written social copy). At 20+ shows per week with 2-4 guests each, this is 40-80 souvenir packages per week produced at zero marginal cost. Pax tracks this as operational efficiency in the Media BU capacity model.
Marquee (Media)
Direct ownership. The Green Room is a Media BU capability. Marquee's daily media prep now includes verifying Green Room readiness (signaling health, episode context populated). Director agent manages OBS feed configuration. Encore triggers the souvenir pipeline. The entire pre-show → live → post-show guest workflow is under Marquee's production authority.
Dependencies
| Dependency | Status | Notes |
|---|---|---|
| Fly.io account + deployment | Confirmed | App: vft-greenroom-signal, region: ord (Chicago) |
| Metered.ca TURN relay | Confirmed | API key in .env, domain: valuefirst.metered.live |
| flyctl CLI in WSL | Confirmed | /home/coach_chris/.fly/bin/flyctl, deploy token in .env |
| signal.valuefirstteam.com DNS | Configured | CNAME to vft-greenroom-signal.fly.dev (via Ionos) |
| OBS Cam 1-4 browser sources | Requires reconfiguration | Set URLs to localhost:3333/greenroom/feed/{1-4} in OBS properties |
| Sanity episode schema | Pending | guestSouvenirs array needs to be added to episode.ts |
| ffmpeg in PATH | Available | Required for souvenir clip extraction |
| Anthropic API key | Confirmed | In .env, used by souvenir AI scripts |
| Mux API credentials | Confirmed | In .env, used for clip upload |
/show-prep writing episode context |
Partial | prepMaterials field needs consistent population for pre-show context |
Verification
- Signaling server:
curl https://vft-greenroom-signal.fly.dev/health→{"status":"ok"} - Guest page: Open
valuefirstteam.com/live/greenroom/{valid-token}→ camera preview loads, signaling connects - Director integration: Refresh dashboard → GREEN ROOM button visible in bottom bar, guest Link buttons generate tokens
- OBS feeds: Open
localhost:3333/greenroom/feed/1in browser → transparent page waiting for assignment - Host page: Open
localhost:3333/greenroom/host?show=vfaidaily→ audio capture, mesh grid - Screen share: Guest shares screen → director clicks Screen → OBS Screen 1 shows content
- VDO.ninja removal:
grep -r "vdo.ninja" broadcast/→ 0 matches - Souvenir pipeline:
node broadcast/scripts/souvenir-pipeline.js --show=vfaidaily --date=2026-04-07 --dry-run→ lists guests, validates metadata
Session Metrics
- Duration: ~18 hours (continuous build session)
- Commits: 12 (Green Room build through souvenir pipeline)
- Files created: 22 new files
- Files modified: 15 existing files
- Lines of code: ~4,800 lines added
- Agents spawned: signaling-audit, mirror-audit (x2), vdo-cleanup (x2), fix-feedback, build-phases, lifecycle-signals, souvenir-pipeline
- External services configured: Fly.io, Metered.ca, Ionos DNS
- Live test: George B. Thomas (first external guest) — feedback incorporated same session
Related Incidents
- VDO.ninja → StreamYard replacement (Mar 2026): StreamYard was cancelled. VDO.ninja was the interim solution. The Green Room is the permanent replacement — fully self-hosted.
- Mux player web component (Apr 3 CAR):
<mux-player>cannot be rendered via React JSX props. Souvenir clip player uses innerHTML per this lesson. - CRLF token failures: All .env files checked for CRLF. Green Room secrets added with Unix line endings.
Documented by V. Capability operational as of 2026-04-07.