Classroom with Fixed Layout and Roles

React web application to demonstrate a fixed location layout assigned by user role in a classroom use case.


Teacher role specific view


This project demonstrates what a classroom application with separate student and teacher views could look like in a react web application.

  • Students have assigned seats to make it easy to see who is attending or absent
  • Students cannot speak until they raise their hand and are called upon
  • Only the teacher may share their screen
Features Tech Stack
  • Role-based permissions
  • Mute remote participants
  • Screen sharing
  • JavaScript/ReactJS
  • Firebase Realtime Database

Getting Started

Clone the repository

git clone
cd meet-dolbyio-classroom

Follow setup instructions

You'll need to complete a few setup steps as described in the README.

✓ Set your App key and App secret in voxeetUtils.js
✓ Setup Firebase Realtime database and update firebaseConfig.js

Key Concepts

Role Based Layouts

Typical video conferencing applications only allow you to choose from a few pre-defined layouts. In this demo, we select a layout that is based on the role or function a participant has during the conference. The needs of a teacher and the needs of a student in a classroom can vary.

Teacher View

Student View

  • Needs to be able to see all students for role-call
  • Needs to be able to speak to all students
  • Needs to be able to share screen for lessons
  • Only needs to be able to see the teacher
  • May be muted to avoid disrupting other students
  • Needs to be able to see the teacher and lessons

Additionally, the student roster and names are assigned a particular location within the layout view. Just like a seating chart in a physical room, the consistency of location can help somebody quickly identify when somebody is missing or find a particular individual.

Firebase Real-time Database

The CommandService allows you to exchange data between clients which can be useful for peer-to-peer messaging workflows. Whenever a new participant joins a conference however, their client application has not received any previous messages but needs a complete record of state. To solve this problem, the classroom application demonstrates using the Firebase Realtime Database to coordinate participant state between clients.

The data model looks like the following:

conference-1234: {
  classRoom: [
           isCalledOn: false,
           isHandRaised: false,
           name: 'Student 1',
           participantId: false
     { ... }

When somebody joins the conference, their participantId is queried and stored in the record of the seat they are assigned. Whenever they click the "raise hand" button the isHandRaised state is updated to true. Likewise, if a teacher calls on a student, the isCalledOn state is set to true. When a student has isHandRaised and isCalledOn, they are no longer muted and are allowed to stream audio to the other participants.

This allows the client application to always be aware of the state of other participants.

Screen Sharing

The teacher can share their screen by clicking the Share Screen button. This triggers a popup to choose from sharing the entire screen, a specific application window, or a separate tab of the web browser.


Choose what to share

By clicking the button, this triggers a call to the startScreenShare() method of the ConferenceService. The button state is also updated in order to trigger a stopScreenShare() call later.

The participant or student perspective will start receiving a new video feed to be displayed. An event streamAdded is emitted by the ConferenceService to identify this change of state. By checking the incoming streams, the client application for participant views can also test that a MediaStreamType is 'ScreenShare'

const screenshareStream = participant.streams.find((el) => {
  return el.type === 'ScreenShare';

 if (screenshareStream) {
          isScreenshare = screenshareStream.getVideoTracks().length > 0;

For additional details, the Presenting article explains how to set this up or for step-by-step instructions see the Getting Started Guide to Implement Screen Sharing may be helpful.

Moderator Control for Muting Participants

The requirement for this application was that students would not be allowed to speak unless called upon. To accomplish this, the entire conference starts without audio:

  conference.join(conf, {
    constraints: {
      audio: false,
      video: true,

Once a student raises their hand and is called upon, then we can startAudio() for that specific participant.

const startAudio = () => {
    .then(() => {})
    .catch((err) => {

Additionally, this application has an effect to measure the audio level and give a visual indicator as a waveform when somebody is speaking.


This can be helpful given the number of reasons audio can be disabled for a participant of a conference.

✓ Audio is Enabled for conference
✓ Hardware (microphone) is plugged in and not muted
✓ Media device (microphone) is not muted by operating system
✓ Media device (microphone) is allowed in browser
✓ Participant is not muted to stop transmitting audio
✓ Remote participant is not muted to stop receiving audio from that stream

This project demonstrates one way of moderating remote participants. The blog post How to Mute Participants in a Conference demonstrates an alternative using the mute() method.


To try out the experience for yourself, visit the classroom demo and invite a friend to join you at that same location.


Event Code

You'll need an invitation code to access this demo website. Please contact [email protected] to obtain instructions on how to access this site.


Students raise hand to be called upon.

Did this page help you?