Skip to main content

Build a broadcast control room

A control room lets a producer see contributors before putting one source on program. The pattern below is a custom React room surface: it demonstrates preview, program, guest invitations, and contributor audio without pretending to be a complete broadcast backend.

Build this: follow the host dashboard tutorial. View the live pattern: open the broadcast control room showcase. Compare it with maintained repositories in the Starter Projects catalog. There is no maintained standalone repository for this pattern yet.

The journey

  1. The producer starts a bounded rehearsal room through an authenticated backend.
  2. Sources appear in a preview matrix: cameras, microphones, and an explicitly consented screen share.
  3. The producer invites a named contributor, previews the source, and uses Take to put the selected source on program.
  4. Contributors remain on the stage and audible while the program source changes.
  5. The producer ends the rehearsal and waits for confirmed room teardown.

Invitation and authority

The producer's backend creates the room, binds a named contributor invitation to the room, and returns short-lived room-scoped join data. A guest can redeem the invitation but cannot self-elevate or mint another role. The application owns labels, preview/program state, and operator permissions; MediaSFU owns room transports, tracks, and participant events.

Room lifecycle

Keep closed, joining, ready, active, and ending visible as product states. Do not enable invitation controls until room readiness and contributor capacity are known. Ending a rehearsal is one operation: stop app-owned work, leave or end the room, and show success only after the room controller confirms that upstream state is clear.

Media identity

Sources, Preview, and Program are different roles, not three names for the same video. Bind a contributor slot to a current member identity before looking up a producer. A screen is a screen identity and uses contain; a local camera may be mirrored only in its self-view. CapsuleRoomAudio mounts contributor voices independently of whichever source is currently on program.

Remote audio

Contributor voices remain mounted when Preview or Program changes. Selecting a source must not silence an approved contributor whose camera is off.

Primary and mini media

The selected program source is primary. Other cameras and the shared screen stay in preview or as secondary contributor cards. Selecting a source does not silence an approved contributor, and an empty slot is not a live participant.

Responsive layout

Keep Sources and Program inside the measured control-room container. At narrow widths, collapse the contributor matrix into a rail and keep Take, invitation, and end actions reachable below the program monitor. The audio renderer remains mounted when a contributor card moves or loses video.

Failure states

Show an actionable message for permission denial, unavailable source, failed join, invitation refusal, capacity changes, a rejected Take, and unconfirmed teardown. Disable only the affected action while it retries; leave the operator with a readable preview and program state instead of a raw transport or parser error.

Cleanup

On explicit end, page exit, or unmount, remove listeners and timers, stop local media work, and call leave/end once. Treat repeated cleanup as safe. Do not label the rehearsal ended until the controller confirms room teardown.

Product evolution

An earlier control-room composition could show a contributor name without a matching member and made preview-to-program switching look like a hidden media transport operation. The stable lesson is to bind slots to current identity and make Sources → Preview → Program → Take explicit application actions while keeping contributor audio independent.

Choose and test your platform

Use the React showcase for source selection, screen binding, invitation flow, independent audio, and cleanup behavior. There is no separate Angular, Vue, React Native, Expo, Flutter, Kotlin, Swift, or Unity starter for this exact control-room layout. When porting it, confirm every required operation in that SDK's guide and test the complete producer/contributor journey on the target.

Release checklist

Use an authenticated backend for reusable credentials, test a real producer and contributor, verify camera, microphone, screen share, remote audio, narrow layout, failed actions, and page-exit cleanup, then add any HLS, recording, moderation, sign-in, or persistence systems your product requires.