Skip to main content
Version: 1.x.x

Virtual Lectures - React

A virtual lecture lets a teacher present to hundreds of students who join from laptops, tablets and phones. Students watch in real time and take part through chat and polls, the teacher brings a student on stage to ask a question, and the lecture can be recorded and captioned for students who missed it. The lecture is built on Interactive Live Streaming (ILS). For a class of up to a few dozen students who talk and come on camera, see Virtual Classroom.

This guide also covers audiences of thousands who mostly watch. Follow the lecture flow as written, then see Scale to Thousands of Students 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 students use.

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

note

VideoSDK runs the live video, audio, chat, recording and HLS delivery for the lecture. Your application owns the course schedule, the student roster, and the learning platform around the lecture.

Set Up the Lecture Session​

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

  • Keep the course schedule in your backend: VideoSDK does not keep the course schedule or the student roster, so keep them in your learning management system. Create the room for the lecture, issue the tokens when it is due, and open the lecture in the application when the teacher is ready to go live.
  • Create a room: Use the Create a Room API to create a room for each lecture. Use the returned roomId as the lecture ID and attach it to the lecture in your course schedule.
  • Validate the room: Before issuing tokens, use the Validate a Room API to ensure the room is valid and available for the lecture. If validation fails, do not issue the tokens, and report the failure to your learning management system.
  • Set participant modes: Join the teacher and any co-teacher in SEND_AND_RECV mode so they publish their camera and microphone and see each other. Join students in RECV_ONLY mode so they receive the lecture in real time without publishing media of their own, 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 teacher's token so the teacher joins the lecture directly and can turn off the camera or microphone of a student on stage. Set allow_join in student tokens so students 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, screen sharing, the whiteboard and bringing a student on stage are available to all participants by default. Show these controls only in the teacher's console to keep the lecture under the teacher's control.

Configure the Student's Devices and Network​

Students join from laptops, tablets and phones, often over home or mobile networks and sometimes part way through the lecture, and most of them only watch. Keep their path to the lecture short.

Check the Network Before the Lecture​

  • 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 a student who only watches. Use the results to select an appropriate starting media configuration and tell the student what to expect from their connection. See Precall Setup.
  • Join the lecture directly: Set joinWithoutUserInteraction to true on MeetingProvider so a student who opens the lecture in the application joins at once in RECV_ONLY mode, with no second screen in the way. See Initialize Live Stream.
  • Hold students on a waiting screen: Show students who open the lecture early a waiting screen until the teacher is present, rather than an empty room. Switch to the lecture when the first SEND_AND_RECV participant joins. See Waiting Screen.

Configure the Teacher's Console​

The teacher runs the lecture from a console, teaching on the whiteboard and slides, taking questions and bringing students on stage. The console should provide controls for teaching, engaging students, managing the stage and controlling the lecture.

Two screens side by side. On the left, a student's laptop shows the shared whiteboard with a diagram, a small teacher video with a note that the teacher is speaking, a raise hand button, a poll asking which answer is correct with four options, and chat. On the right, the teacher's console shows the whiteboard, the two people on stage with one student highlighted, buttons for whiteboard, share screen, start poll, invite on stage and end lecture, a raised hands list with invite buttons, and a poll results panel

Prepare the Teacher's Stage Before Going Live​

The teacher'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 into the meeting

  • Check devices and permissions before going live: A lecture goes out as it happens and the teacher cannot see what students see, so give the teacher 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 the teacher'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 teacher 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 the teacher 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 replace a busy staff room with a clean backdrop, or to blur it, so students see a tidy picture wherever the teacher presents from. Virtual backgrounds are supported on desktop browsers.
  • Suppress background noise: Use the AI Noise Suppression plugin to filter the noise of a corridor or a street from the teacher's microphone, so students hear the lecture clearly.
  • Brand the layout: Use a custom template to give the lecture a course-branded layout, with a title, a logo or the agenda composed into the picture rather than drawn over it on each device. See Customized Live Stream.

Control Your Own Media and Devices​

Teach on the Whiteboard and Share Slides​

Engage Students During the Lecture​

  • Take questions in chat: Chat built on PubSub lets students ask questions at lecture scale. Use a group chat to reach everyone. Set persist to true for messages that should still be displayed when a student rejoins or joins later. Persisted messages can also be downloaded as CSV from the VideoSDK session dashboard for the lesson record. See Chat during Live Stream.
  • Support private conversations: Pass the recipient's participantId in the sendOnly option of publish() to send a message to one person, so a student can ask the teacher for help and the teacher can reply without the rest of the class seeing it. See Private Chat.
  • Check understanding with polls: Publish a poll over PubSub and show the results on every screen as votes arrive. Set persist to true on the poll messages so students who join mid-lecture see the poll and where the vote stands. See Audience Polls.
  • Show reactions: Publish reactions as emojis over PubSub and animate them on every screen, so the teacher gets feedback from a quiet audience. See Reactions.
  • Share handouts and files: Use uploadBase64File() from the useFile hook to upload a worksheet or a PDF to VideoSDK's temporary storage. Share the returned fileUrl by publishing it with publish() over PubSub, and use fetchBase64File() to retrieve the file on a student's device. Temporary files are deleted when the meeting ends, so save anything students need to keep in your own storage. See File Sharing.
  • Keep shared state synchronized: Use the Realtime Store for small state that should stay consistent across participants, such as the current slide or an open poll. Use setValue() and getValue() from the useRealtimeStore hook to write and read values, and onValueChanged to respond to updates. After a reconnect, listen to onMeetingStateChanged and read the current values again with getValue() when the state returns to CONNECTED. See Realtime Store.

Bring Students on Stage​

A sequence diagram with three lifelines: the teacher's application, VideoSDK, and the student's application. Step one, the student raises a hand or asks a question in chat and the teacher picks them. Step two, the teacher publishes an invitation on a change mode topic addressed to that student, who sees a dialog. Step three, the student's application calls changeMode to send and receive and starts publishing camera and microphone. Step four, VideoSDK raises the participant mode changed event and the teacher's application pins the student so everyone sees them. Step five, the student calls changeMode back to receive only when done and is unpinned

  • Let students raise their hands: Use a dedicated PubSub topic so a student who wants to speak can raise a hand, and list them in the teacher's console in the order they raise their hands. Students join receive-only, so raising a hand is how they ask for a voice. See Raise Hand.
  • Invite the student on stage: Publish the invitation on a PubSub topic addressed to that student, since changeMode() only changes the mode of the participant who calls it. When the student accepts, have their application switch to SEND_AND_RECV with changeMode() and start publishing. After the answer, the student can switch back to RECV_ONLY. See Invite Guest on Stage and Change Mode.
  • Pin the student on stage: Handle onParticipantModeChanged from the useMeeting hook in the teacher's application to learn that the student is on stage, and call pin() from the useParticipant hook to put them in the picture for everyone. Call unpin() to return the layout to normal when they switch back to RECV_ONLY. See Pin/Unpin Participant and Manage On-Screen Participants.

Control the Lecture​

Configure the Lecture Screen on Both Sides​

These components are built into both the student's application and the teacher's console.

Display the Lecture​

  • Render only the teacher and guests: Show video and audio only for the teacher and for students brought on stage, who are the participants in SEND_AND_RECV mode. 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 teacher fills the student's screen while a guest on stage stays in a smaller tile, and it mirrors the local preview. See Display Audio and Video.
  • Keep the lecture visible with Picture-in-Picture: Use Picture-in-Picture to keep the lecture visible in a floating window when a student opens notes or an assignment. See Picture-in-Picture Mode.
  • Keep large lectures smooth: With hundreds of students, show each screen only the streams it needs, so every device stays smooth. For layout, pagination and subscription guidance at that size, see Handle Large Rooms.

Show Participant Status​

Keep the Session Reliable​

These controls apply to both the student's application and the teacher's console.

Handle Network Changes During the Lecture​

Network conditions can change during a lecture. Students often join from home or mobile networks, while the teacher may present from a classroom or a lecture hall. 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 students and the teacher when network conditions affect lecture quality and when conditions improve. See Monitoring Network Quality for available events and Optimize for Low Bandwidth Networks for recommendations before and during the lecture.
  • 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 students know the lecture is recovering rather than over, and return to the course 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 student's application and the teacher's console, and send relevant diagnostic details to your monitoring service so failures across lectures stay visible to your team. Avoid including student data in logs. See Error Events.
  • Follow integration guidelines: Review the User Experience Guidelines and Developer Experience Guidelines to build a reliable, accessible lecture experience.

Recording​

Configure recording, storage delivery, and encryption based on what the lesson record needs. You can start recording when the teacher goes live and configure transcription alongside it. If recording is mandatory, verify that it has started before proceeding with the lecture. The recording file, the transcript and the summary are delivered once the lecture ends, so students who missed it can catch up and everyone can revise. 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 lesson record needs. See Recording Overview.

  • Meeting recording: Records the entire lecture, every host and shared content, into one file with a composed layout. Record it with the same custom template as the live lecture, so the replay carries the branded layout students saw live. See Record Live Stream and Customized Live Stream.
  • Participant recording: Records one participant's audio and video into a single file, such as the teacher alone for a clean copy of the lecture. 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 Lecture​

  • Start recording automatically: If the lecture must be recorded from the beginning, show students a consent notice before the lecture 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 teacher's console until the recording starts. The backend receives the recording-started webhook, while the applications receive onRecordingStateChanged with RECORDING_STARTED. If the teacher 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 lecture, or while stopping. If recording fails at the start and recording is mandatory, do not start the lecture. If recording is optional, you can continue without it. If recording fails during the lecture, 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 lecture 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 file to the lecture in your course platform. 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 lesson record needs before configuring either.

Transcription​

Live captions help students who are hard of hearing or learning in a second language, while the post-lecture transcript and summary become revision notes. Transcription is not available for an API key with Recording Encryption enabled.

Show Live Captions​

Generate the Transcript and Summary​

  • Generate a post-lecture transcript and summary: Pass a transcription configuration to startRecording(), set enabled to true, and provide a summary.prompt that specifies the sections your students need, such as topics covered, key points and homework. Retrieve the transcript and summary using the Fetch Post Transcriptions & Summary API or the webhook URL provided to startRecording(). See Post Transcription & 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: If some students learn in a second language, use Realtime Translation to help them follow the lecture in their own language.

Scale to Thousands of Students with HLS​

When most of your audience watches, use HLS to deliver the lecture through a player instead of the room. HLS adds a typical delay of 15 to 30 seconds. Students can still chat, and a student who wants to speak is brought on stage with the same flow as above. Everything above, from session setup to the teacher'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, 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.
  • Choose how the lecture looks: Pass a config to startHls() to choose the layout, the theme, the quality and the orientation. The sidebar layout shows shared slides in the main view and pinned participants in a side grid, and the spotlight layout shows only the slides while sharing. Only pinned participants appear in those layouts, so pin the teacher. Set mode to audio for a lecture that students follow by listening, which suits weaker connections. See Start HLS.
  • Play the stream: Play the playbackHlsUrl for students with an HLS player built on hls.js. This URL is the live stream with playback support, so students can go back in the stream. The livestreamUrl is the live stream without playback support. See Setup HLS Player.
  • Let HLS students chat: Have students who watch over HLS join the room in SIGNALLING_ONLY mode, which carries messages and presence without any media, so they can still chat, take part in polls and be counted. See Chat using PubSub.
  • Bring an HLS student on stage: A student in SIGNALLING_ONLY mode raises a hand, accepts the invitation and calls changeMode() to SEND_AND_RECV, as described in Bring Students on Stage. Students watching over HLS are behind the live lecture, so the teacher can call a student by name before inviting them. See Raise Hand and Change Mode.
  • Show a preview of the lecture: While HLS runs alongside the interactive lecture, 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 course listing, so students 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 lecture live in your course platform and show it as ended afterwards. The hls-playable webhook carries the playbackHlsUrl and livestreamUrl, so your backend can hand the playback URL to students 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 a lecture 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.

Meet Compliance Requirements​

Configure these session-wide controls to align your lectures with your institution'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 student's location. See Geo Fencing.
Allow or restrict access by locationUse Geo IP Restriction to allow or deny access based on the student's IP address and your geographic rules. 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 schools and universities in the EU, and SOC 2 Type II, ISO 27001 and CERT-IN for institutional 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 lecture, 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-lecture transcript and summary, since post transcription runs on the recording file. Realtime transcription is not available when E2EE is enabled.

Firewall and Debugging​

Teachers often present from a school or campus network behind a firewall, and some students may watch from restricted networks as well. Configure firewall rules before the first lecture to ensure the required VideoSDK services are reachable. If a lecture 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 teacher'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 lecture: Run runPreCallTest() from the lecture hall'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 lecture 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