Skip to main content
Version: 1.x.x

Virtual Events and Webinars - React

Virtual events let speakers present to attendees in town halls, workshops, product launches, creator streams and audio rooms. Attendees react in real time and come on stage for questions, and the event can be recorded and transcribed for a replay. The event is built on Interactive Live Streaming (ILS). An audio room is the same event with cameras off.

This guide also covers audiences of thousands who mostly watch. Follow the event flow as written, then see Scale to Thousands of Viewers with HLS for the steps HLS adds.

If you are new to VideoSDK, start with Introduction and Integrate React SDK, and check Supported Browsers for the devices your attendees use.

Architecture of a virtual event deployment on VideoSDK. The attendee's device and the host's console get tokens from your backend and exchange encrypted audio, video and data with VideoSDK. Your backend holds tokens, registration and the agenda and event record and uses REST APIs and webhooks. The host's traffic passes your firewall and an optional proxy. VideoSDK provides live stream rooms, chat, transcription, HLS playback and RTMP out, recordings in your cloud storage and session-wide security controls.

note

VideoSDK runs the live video, audio, chat, recording and HLS delivery for the event. Your application owns the registration list, the tickets, the agenda, and the experience around the event.

Set Up the Event Session​

Prepare the room and generate participant tokens on your backend before the host goes live.

  • Keep registration and the agenda in your backend: VideoSDK does not keep the registration list, the tickets or the agenda, so keep them in your event platform. Create the room for each session, issue the tokens when it is due, and open the event in the application when the host is ready to go live.
  • Create a room: Use the Create a Room API to create a room for each event. Use the returned roomId as the event ID and attach it to the event in your registration system.
  • Validate the room: Before issuing tokens, use the Validate a Room API to ensure the room is valid and available for the event. If validation fails, do not issue the tokens, and report the failure to your event platform.
  • Set participant modes: Use SEND_AND_RECV mode for the host, speakers and panelists so they publish their camera and microphone and see each other. Use RECV_ONLY mode for attendees so they receive the stage in real time without publishing and take part through chat, polls, reactions and raised hands. See Host vs Audience Modes, Manage Roles and Initialize Live Stream.
  • Configure participant permissions: Set allow_join and allow_mod in the host's token so the host joins the event directly and can turn off the camera or microphone of a speaker or a guest on stage. Set allow_join in speaker and attendee tokens so they join directly. Include roomId and participantId in every token payload, with version set to 2. See Authentication and Tokens.
  • Gate controls by role: Features such as recording, bringing an attendee on stage and streaming out to social platforms are available to all participants by default. Show these controls only in the host's console to keep the program under the host's control.

Configure the Attendee's Devices and Network​

Attendees join from laptops and phones, often over corporate or mobile networks and often part way through the program, and most of them only watch. Keep their path to the event short.

Check the Network Before the Event​

  • Assess network quality: Use runPreCallTest() to evaluate uplink and downlink quality on a scale from 1 (BAD) to 5 (EXCELLENT), along with the factors affecting each score. The downlink score matters most for an attendee who only watches. Use the results to select an appropriate starting media configuration and tell the attendee what to expect from their connection. See Precall Setup.
  • Join the event directly: Set joinWithoutUserInteraction to true on MeetingProvider so an attendee who opens the event from their ticket joins at once in RECV_ONLY mode, with no second screen in the way. See Initialize Live Stream.
  • Hold attendees on a waiting screen: Show attendees who arrive early a waiting screen until a host is present, rather than an empty room. Switch to the stage when the first SEND_AND_RECV participant joins. See Waiting Screen.

Configure the Host's Console​

The host runs the program from a console, presenting with the speakers, managing who is on stage and taking questions from the audience. The console should provide controls for engaging attendees, bringing them on stage, connecting with other streams and controlling the event.

Two screens side by side. On the left, an attendee's laptop shows the stage with two speakers, a live badge with an attendee count, captions under the stage, a chat panel, a poll, and buttons for react and raise hand. On the right, the host's console shows the stage with the speakers and a pinned attendee asking a question, a Q&A queue with raised hands and bring on stage buttons, buttons for start poll, captions and go live on YouTube, and a panel showing attendance and stream-out status

Prepare the Speakers' Stage Before Going Live​

The speaker's green room screen and the checks behind it. On the left, a phone shows a camera preview, camera and microphone selectors, a microphone test with a level meter, a speaker test with a play button, a connection line reading good connection, ready for video, and a go live button. On the right, four cards list the checks: permissions granted, devices listed and refreshed when a headset is connected, microphone and speaker tested, and network measured with a quality score and factors, followed by a card saying the choices are carried onto the stage

  • Check devices and permissions before going live: A broadcast goes out as it happens and a speaker cannot see what attendees see, so give each speaker a green room screen that confirms a working setup before going live. Use checkPermissions() and requestPermission() from the useMediaDevice hook to check and request camera and microphone access, getCameras() and getMicrophones() to list devices, and onDeviceChanged to refresh the list when a device is connected. Complete the check with a camera preview and a microphone and speaker test. See Precall Setup.
  • Assess network quality: Use runPreCallTest() to evaluate each speaker's uplink and downlink quality on a scale from 1 (BAD) to 5 (EXCELLENT), along with the factors affecting each score. Use the results to select an appropriate starting media configuration before the speaker goes live. See Precall Setup.
  • Apply the verified setup: Pass the selected camera and microphone devices, their enabled states, and the chosen media configuration to MeetingProvider, so each speaker goes live with the setup they verified. The configuration can include a custom camera track created with createCameraVideoTrack(). See Precall Setup for recommended configurations based on the test results and Optimize Video Tracks.
  • Apply a virtual background: Use the Virtual Background plugin to give every speaker the same branded backdrop, or to blur their surroundings, so the stage looks consistent wherever each speaker joins from. Virtual backgrounds are supported on desktop browsers.
  • Suppress background noise: Use the AI Noise Suppression plugin to filter background noise from a speaker joining from a hotel room or a conference floor, so attendees hear every word.
  • Brand the stage: Use a custom template to compose the stage into a produced picture, with lower thirds, a logo, a sponsor strip or an agenda, rather than drawing overlays on each device. See Customized Live Stream.

Control Your Own Media and Devices​

Engage Attendees in Real Time​

  • Use chat: Chat built on PubSub lets attendees ask questions at event scale. Use a group chat to reach everyone, and pass the attendee's participantId in the sendOnly option of publish() for a private chat, so the host or a moderator can answer one attendee directly. Set persist to true when publishing messages to retain them for the session. Persisted messages can be downloaded as CSV from the VideoSDK session dashboard for the event record. See Chat during Live Stream and Private Chat.
  • Show reactions: Publish reactions as emojis over PubSub and animate them on every screen, so speakers get instant feedback from an audience that would otherwise be silent. See Reactions.
  • Run a poll: Publish a poll over PubSub to give the host a read on the room mid-session, and aggregate the results on every screen as votes arrive. See Audience Polls.
  • Indicate who is speaking: Use onSpeakerChanged from the useMeeting hook to show who is speaking, which helps a panel discussion follow the conversation. See Active Speaker Indication.

Bring Attendees on Stage​

A sequence diagram with three lifelines: the host's application, VideoSDK, and the attendee's application. Step one, the attendee publishes a raise hand message and the host's console queues them for questions. Step two, the host publishes an invitation on a change mode topic addressed to that attendee, who accepts. Step three, the attendee's application calls changeMode to send and receive and their camera and microphone go live. Step four, VideoSDK raises the participant mode changed event and the host pins the attendee next to the speaker. Step five, the attendee calls changeMode back to receive only after the answer and is unpinned

  • Let an attendee raise a hand: Use a dedicated PubSub topic so an attendee who wants to ask can raise a hand, and queue them in the host's console. See Raise Hand.
  • Invite the attendee on stage: Publish the invitation on a PubSub topic addressed to that participant, since changeMode() only changes the mode of the participant who calls it. When the attendee accepts, have their application switch to SEND_AND_RECV with changeMode() so their camera and microphone go live. See Invite Guest on Stage and Change Mode.
  • Pin the guest on stage: Handle onParticipantModeChanged from the useMeeting hook in the host's application to learn that the attendee is on stage, and call pin() to put them next to the speaker. After the answer, have the attendee switch back to RECV_ONLY and call unpin(). See Pin/Unpin Participant.

Connect with Other Streams​

For collaborative sessions, cross-promotions and multi-session conferences, connect your stream with other streams and platforms.

  • Relay a co-host or panel into another stream: Use requestMediaRelay() from the useMeeting hook to relay a host's audio, video or screen share into another live stream, for a collaborative session or a cross-promotion. See Relay Media (PK Host).
  • Move attendees between sessions: Have each attendee's application call switchTo() from the useMeeting hook with the next meeting's ID to move from one session of a multi-session conference to the next, so attendees switch without leaving and rejoining. See Switch Live Stream.
  • Stream out to social platforms: Use startLivestream() from the useMeeting hook, with the platform's stream URL and key, to send the event out to YouTube, LinkedIn or any RTMP platform while the interactive event keeps running in your application. Use stopLivestream() to end it, and handle onLivestreamStateChanged to learn when the stream-out starts and stops. See RTMP Livestream.

Control the Event​

Configure the Event Screen on Both Sides​

These components are built into both the attendee's application and the host's console.

Display the Stage​

  • Render only the hosts: Render audio and video for SEND_AND_RECV participants only and nothing for the audience, since only hosts publish media, which keeps every attendee's screen clean and their device's load low. See Rendering Host and Audience Views.
  • Render each host's video: Use the VideoPlayer component to render each host's video. It requests the video quality that matches the tile size, so the speaker fills the attendee's screen while the rest of the panel stays in smaller tiles, and it mirrors the local preview. See Display Audio and Video.
  • Keep the stage visible with Picture-in-Picture: Use Picture-in-Picture to keep the stage visible in a floating window when an attendee opens the agenda or a sponsor page, or the host opens the run of show. See Picture-in-Picture Mode.
  • Plan for a large audience: An audience of thousands calls for a deliberate choice of which streams each screen renders and subscribes to. Follow the guidance for large rooms on layout, pagination and subscriptions at that size. See Handle Large Rooms.

Show Participant Status​

Keep the Session Reliable​

These controls apply to both the attendee's application and the host's console.

Handle Network Changes During the Event​

Network conditions can change during an event. Attendees often join from corporate or mobile networks, while speakers may present from a venue, a hotel or a home office. VideoSDK adapts video quality to available bandwidth and provides network and media events that help your application respond to changing conditions.

  • Keep both sides informed: Use the relevant quality events to notify attendees and speakers when network conditions affect event quality and when conditions improve. See Monitoring Network Quality for available events and Optimize for Low Bandwidth Networks for recommendations before and during the event.
  • Show the connection state: Use onMeetingStateChanged from the useMeeting hook to follow the connection through CONNECTING, CONNECTED, RECONNECTING and DISCONNECTED. Show a reconnecting indicator on both screens while the state is RECONNECTING, so attendees know the event is recovering rather than over, and return to the agenda screen when it reaches DISCONNECTED. See Meeting Connection State Events.

Handle Errors and Follow Best Practices​

  • Handle SDK errors: Use onError from the useMeeting hook to receive error information when a meeting operation fails. Display actionable feedback in the attendee's application and the host's console, and send relevant diagnostic details to your monitoring service so failures across events stay visible to your team. Avoid including attendee data in logs. See Error Events.
  • Follow integration guidelines: Review the User Experience Guidelines and Developer Experience Guidelines to build a reliable, accessible event experience.

Recording​

Configure recording, storage delivery, and encryption based on what the replay needs. You can start recording when the host goes live and configure transcription alongside it. If recording is mandatory, verify that it has started before proceeding with the event. The recording file, the transcript and the summary are delivered once the event ends, so the replay can go to registrants who missed it and the summary can follow as the event notes. The recording's delivery destination and encryption depend on your configured storage and encryption settings.

Choose the Recording Type​

VideoSDK offers three types of recording. Choose the one that matches what your replay needs. See Recording Overview.

  • Meeting recording: Records the entire event, every host and shared content, into one file with a composed layout. Record it with the same custom template as the live stage, so the replay carries the produced picture attendees saw live. Set mode to audio in the recording config for an audio room, so the file is smaller. See Record Live Stream and Customized Live Stream.
  • Participant recording: Records one participant's audio and video into a single file, such as the keynote speaker alone for a session library. Start it with the Start Participant Recording API, and use the matching participant recording API to stop it. See Participant Recording (Individual).
  • Participant track recording: Records a single audio or video track of one participant as its own file. Start it with the Start Track Recording API, and use the matching track recording API to stop it. See Participant Track Recording.

Record the Event​

  • Start recording automatically: If the event must be recorded from the beginning, show attendees a consent notice before the event starts, then add a recording entry to autoStartConfig when creating the room with the Create a Room API. Use this entry to configure transcription, recording config, and the custom recording template templateUrl as needed. See Create a Room.
  • Wait for recording confirmation: Show a loader in the host's console until the recording starts. The backend receives the recording-started webhook, while the applications receive onRecordingStateChanged with RECORDING_STARTED. If the host starts recording manually using startRecording() from the useMeeting hook, show the same loader until the started status arrives. See Record Live Stream and Webhook and Events.
  • Handle recording failures: VideoSDK sends the recording-failed webhook if recording fails while starting, during the event, or while stopping. If recording fails at the start and recording is mandatory, do not start the event. If recording is optional, you can continue without it. If recording fails during the event, you can retry or end the session. To close the room automatically when recording fails, configure the onFailure option as described below. See Recording Failed Webhook.
  • Close the room automatically: If recording is mandatory, configure VideoSDK to close the room when recording fails. Add an onFailure entry to the recording section of autoStartConfig, or include it in the request body when starting recording from your backend. Set action to close-room and configure waitTime in seconds. We recommend 30 seconds. See the onFailure parameter and example request body in Create a Room and Start Recording.
  • Stop the recording and store the file: The recording stops automatically when the event ends. To stop it earlier, call stopRecording() from the useMeeting hook or the Stop Recording API from your backend. Your backend receives the recording-stopped webhook with the fileUrl, filePath and sessionId, so it can attach the replay to the event in your registration system. To look the file up later, use the Fetch Recordings API to list the recordings of a room or the Fetch a Recording API to retrieve one by its id. See Webhook and Events.

Store Recordings in Your Own Storage​

  • Configure your own storage: Use Configure Recording Storage in the dashboard to deliver recordings to your own AWS S3, Azure Blob or GCP bucket. It is set per API key and includes a test step.
  • Upload with a presigned URL: When stored credentials are not allowed, generate a presigned URL on your backend and pass it to the Start Recording API, so the recording is uploaded to one object for a limited time.
note

VideoSDK uploads recordings to your storage with the credentials you set up. If your storage only accepts uploads from approved IP addresses, you will need to approve VideoSDK's static IP addresses. Contact us to request them.

Encrypt and Decrypt Recordings​

  • Encrypt recordings at rest: Turn on Recording Encryption for the API key in the dashboard, under Cloud Storage Configuration, and provide an RSA public key. Each recording is encrypted with its own AES key before upload. AES-256-GCM is recommended.
  • Decrypt with your private key: Each recording arrives as three files: the encrypted recording, the wrapped AES key and a metadata file. Decrypt them on your side with your private key. The guide includes a Node.js example.
note

Recording Encryption and transcription cannot be enabled together on one API key, since transcription runs on unencrypted recordings. Decide per API key which your replay needs before configuring either.

Transcription​

Live captions meet accessibility requirements and help attendees following in a second language, while the post-event transcript and summary become the event notes. Transcription is not available for an API key with Recording Encryption enabled.

Show Live Captions​

Generate the Transcript and Summary​

Choose the Language​

  • Set the spoken language: Pass the appropriate language code to startTranscription(). The default is en. See Supported Languages for available codes, including regional variants such as en-IN, hi, and es-419.
  • Translate captions when needed: For an international audience, use Realtime Translation to caption each speaker in the attendee's own language.

Scale to Thousands of Viewers with HLS​

When most of your audience watches rather than interacts, use HLS to deliver the stage through a player instead of the room. HLS adds a typical delay of 15 to 30 seconds. Everything above, from session setup to the host's console, recording, transcription, compliance and firewall, applies as written.

  • Start and stop HLS: Call startHls() from the useMeeting hook to start the HLS output with your chosen layout, quality and orientation, and stopHls() to end it. Handle onHlsStateChanged to show a loader while the state is HLS_STARTING or HLS_STARTED. At HLS_PLAYABLE, the event carries the playbackHlsUrl and livestreamUrl. See Start HLS and Stop HLS.
  • Play the stream: Play the playbackHlsUrl for viewers with an HLS player built on hls.js. This URL is the live stream with playback support, so viewers can go back in the stream. The livestreamUrl is the live stream without playback support. See Setup HLS Player.
  • Show a preview of the stream: While HLS runs alongside the interactive stream, call the Fetch an HLS Thumbnail API from your backend with the room's roomId. Show the returned image as a preview card in your listing of live events, so attendees can see what is on air before they open it. See Generate HLS Thumbnail.
  • Track HLS from your backend: Your backend receives the hls-starting, hls-started, hls-playable, hls-stopping and hls-stopped webhooks, so you can mark the event live in your listing and show it as ended afterwards. The hls-playable webhook carries the playbackHlsUrl and livestreamUrl, so your backend can hand the playback URL to attendees who only watch and never join the room. See Webhooks List.
  • Control HLS from your backend: To run HLS without a console, use the Start HLS API and the Stop HLS API. Check whether an event's stream is live with the Fetch Active HLS API, retrieve one by its id with the Fetch an HLS API, and remove one you no longer need with the Delete an HLS API. Pair the live check with the thumbnail API to build a listing of live events with preview cards.
  • Let HLS viewers chat: Have viewers join the room in SIGNALLING_ONLY mode, which carries messages and presence without media, so they can chat and still be counted in attendance. Chat, reactions and polls work for these viewers. Bringing a viewer on stage is not possible over HLS. See Chat using PubSub.

Meet Compliance Requirements​

Configure these session-wide controls to align your event with your organization's data protection policies and regional requirements.

RequirementControl
Keep media within a regionUse Geo Fencing to restrict connections to VideoSDK servers in your specified regions, regardless of the attendee's location. See Geo Fencing.
Allow or restrict access by locationUse Geo IP Restriction to allow or deny access based on the attendee's IP address and your geographic rules, such as an event licensed for one region. See Geo IP Restriction.
Encrypt media end to endUse E2EE to encrypt media on the sender's device and decrypt it only on the receiver's device, preventing intermediaries, including VideoSDK servers, from accessing the media. Your application is responsible for generating and distributing encryption keys. See E2EE Setup.
Meet regulatory requirementsVideoSDK offers GDPR compliance with EU data residency and a Data Processing Agreement for attendees in the EU, and SOC 2 Type II, ISO 27001 and CERT-IN for corporate procurement and vendor reviews. GDPR compliance and the Data Processing Agreement are available as add-ons.
note

If E2EE is enabled and you want to record or transcribe the event, use a custom recording template. See Customized Live Stream.

  • Recording: Build the template with the React or JavaScript SDK and enable E2EE in it using the same key provider and shared key as your application, so the template can decrypt the media for recording. Deliver the key securely from your backend to the template over HTTPS rather than including it in the templateUrl, then start the recording using the template's templateUrl.
  • Transcription: Use the same template recording for the post-event transcript and summary, since post transcription runs on the recording file. Realtime transcription is not available when E2EE is enabled.

Firewall and Debugging​

Speakers often present from a venue or office network behind a firewall, and many attendees watch from corporate networks with their own restrictions. Configure firewall rules before the first event to ensure the required VideoSDK services are reachable. If a session fails to connect, use the checks below to identify potential network restrictions.

Allow VideoSDK Traffic Through Your Firewall​

  • Allow VideoSDK domains: The simplest approach is to allow all subdomains of *.videosdk.live over TCP and UDP on all ports. This covers the API, signaling, media, and TURN servers. See Firewall Setup.

  • Allow specific hosts and ports: If your network policy requires explicit firewall rules, allow the following hosts and ports. VideoSDK can use the fallback transport when the primary connection is unavailable.

    ServerHostPrimaryFallback
    APIapi.videosdk.liveTCP 443—
    Signaling*.rm.videosdk.live, or the regional hosts listed in the Firewall Setup guideTCP 443—
    Mediamedia.videosdk.liveUDP 40000–60000TCP 40000–60000
    TURNturn.videosdk.liveUDP and TCP 3478TCP 443

    Also allow sdk.videosdk.live over TCP 443 if your console loads the SDK or the PubSub worker from the VideoSDK CDN. The full-access policy already covers it.

  • Allow the PubSub worker in your Content Security Policy: PubSub runs in a web worker created from a blob: URL. If the host's console runs under a strict Content Security Policy, allow blob: in the worker-src directive, or pass pubsubWorkerUrl to MeetingProvider to load a pre-built worker from the VideoSDK CDN or your own domain. See CSP policy for PubSub.

  • Use Cloud Proxy for restricted networks: If the required ports cannot be opened, use Cloud Proxy to route media through the proxy servers you specify. Choose UDP over TCP (the default), Force UDP, or Force TCP according to your network restrictions.

Debug Connection Issues​

  • Test the network before the first event: Run runPreCallTest() from the venue's network after configuring the firewall. The test checks whether a call can transmit media in both directions. If it fails despite internet access, review the required hosts and ports above. See Precall Setup.
  • Check UDP connectivity: Set preferredProtocol to TCP_ONLY in MeetingProvider and try connecting again. If the stream succeeds over TCP but fails with the default UDP_OVER_TCP configuration, investigate whether UDP traffic is blocked on the media or TURN ports. You can also configure Cloud Proxy for the affected network.
  • Inspect connection errors: Use onError from the useMeeting hook to capture the error code and message when a connection fails. Use this information to investigate whether the failure occurred during the API, signaling, or media stage, and forward relevant diagnostics to your monitoring service to identify affected networks. See Error Events.
  • Verify media flow: Use getTransportStats() from the useParticipant hook to inspect transport statistics and check whether traffic is flowing in both directions. If one direction shows no bitrate, investigate the corresponding network path and firewall rules. See Monitoring Transport Stats.
  • Collect connection logs: Call setLogLevel() with Constants.LogLevel.DEBUG to collect detailed diagnostics while reproducing the issue. After troubleshooting, restore the log level to INFO or NONE as appropriate. See Log Level.

API Reference​

The API references for all the methods and events utilized in this guide are provided below.

Got a Question? Ask us on discord