New Capability: Green Room Guest Experience

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)

  1. Open Director Dashboard at http://localhost:3333
  2. Select show from timeline
  3. Click "Link" on any guest card → Green Room URL copied to clipboard
  4. 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

  1. Signaling server: curl https://vft-greenroom-signal.fly.dev/health{"status":"ok"}
  2. Guest page: Open valuefirstteam.com/live/greenroom/{valid-token} → camera preview loads, signaling connects
  3. Director integration: Refresh dashboard → GREEN ROOM button visible in bottom bar, guest Link buttons generate tokens
  4. OBS feeds: Open localhost:3333/greenroom/feed/1 in browser → transparent page waiting for assignment
  5. Host page: Open localhost:3333/greenroom/host?show=vfaidaily → audio capture, mesh grid
  6. Screen share: Guest shares screen → director clicks Screen → OBS Screen 1 shows content
  7. VDO.ninja removal: grep -r "vdo.ninja" broadcast/ → 0 matches
  8. 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.