Implement Screen Sharing

This tutorial guides how to implement a screen sharing feature to the conference application.

Start sharing a screen

Layout editing

Open the index.html file and add:

  • A button with the id start-screenshare-btn as a child of the actions div
  • A div with the id screenshare-container after the video-container div
<div id="actions">
  ...
  <button id="start-screenshare-btn" disabled>Start screen share</button>
</div>
...
<div id="video-container"></div>
<!-- add the screenshare-container here -->
<div id="screenshare-container"></div>

Interface linking

Get element from the document

Open the ui.js file and declare the start-screenshare-btn in the initUI:

const startScreenShareBtn = document.getElementById("start-screenshare-btn");

Disable/enable button

Then, edit the joinButton onclick handler to enable the startScreenShareBtn when the conference is joined:

... => VoxeetSDK.conference.join(conference, {}))
        .then(() => {
            ...
            startScreenShareBtn.disabled = false;

And edit the leaveButton onclick handler to disable the startScreenShareBtn when the conference is left:

leaveButton.onclick = () => {
  // Leave the conference
  VoxeetSDK.conference
    .leave()
    .then(() => {
      joinButton.disabled = false;
      leaveButton.disabled = true;
      startScreenShareBtn.disabled = true;
      stopScreenShareBtn.disabled = true;
    })
    .catch((err) => console.error(err));
};

Logic implementation

Onclick handler

Then, write the startScreenShareBtn onclick handler in the initUI function:

startScreenShareBtn.onclick = () => {
  VoxeetSDK.conference
    .startScreenShare()
    .then(() => {
      startScreenShareBtn.disabled = true;
    })
    .catch((err) => console.error(err));
};

Event handler

Note: When a user starts sharing a screen, a streamAdded event is triggered.

Open the ui.js file and write a new function called addScreenShareNode that creates a video node and attaches the screen stream to it:

const addScreenShareNode = (stream) => {
  const screenShareContainer = document.getElementById("screenshare-container");
  let screenShareNode = document.getElementById("screenshare");

  if (screenShareNode) {
    return alert("There is already a participant sharing their screen!");
  }
  screenShareNode = document.createElement("video");
  screenShareNode.autoplay = "autoplay";
  navigator.attachMediaStream(screenShareNode, stream);

  screenShareContainer.appendChild(screenShareNode);
};

Open the client.js file and add a condition upon receiving the streamAdded event to handle the case where the stream.type is ScreenShare:

VoxeetSDK.conference.on("streamAdded", (participant, stream) => {
  if (stream.type === "ScreenShare") {
    return addScreenShareNode(stream);
  }

  if (stream.getVideoTracks().length) {
    // Only add the video node if there is a video track
    addVideoNode(participant, stream);
  }

  addParticipantNode(participant);
});

Stop sharing a screen

Layout editing

Open the index.html file and add a button with the id stop-screenshare-btn as a child of the actions div:

<button id="stop-screenshare-btn" disabled>Stop screen share</button>

Interface linking

Get element from document

Open the ui.js file and declare stopScreenshareBtn in initUI:

const stopScreenShareBtn = document.getElementById("stop-screenshare-btn");

Enable/disable the button

Edit the startScreenShareBtn onclick handler to enable the button to stop sharing the screen:

startScreenShareBtn.onclick = () => {
  VoxeetSDK.conference
    .startScreenShare()
    .then(() => {
      startScreenShareBtn.disabled = true;
      stopScreenShareBtn.disabled = false;
    })
    .catch((err) => console.error(err));
};

Then, edit the leaveButton onclick handler to disable the button when the conference is left:

leaveButton.onclick = () => {
  VoxeetSDK.conference
    .leave()
    .then(() => {
      joinButton.disabled = false;
      leaveButton.disabled = true;
      startScreenShareBtn.disabled = true;
      stopScreenShareBtn.disabled = true;
    })
    .catch((err) => console.error(err));
};

Logic implementation

Onclick handler

Open the ui.js file and write the onclick function for the stopScreenShareBtn in the initUI function:

stopScreenShareBtn.onclick = () => {
  VoxeetSDK.conference
    .stopScreenShare()
    .then(() => {
      startScreenShareBtn.disabled = false;
      stopScreenShareBtn.disabled = true;
    })
    .catch((err) => console.error(err));
};

Event handler

Note: When a user stops sharing a screen, a streamRemoved event is triggered.

Open the ui.js file and write a new function called removeScreenShareNode that creates a video node and attaches the screen related stream to it:

const removeScreenShareNode = () => {
  let screenShareNode = document.getElementById("screenshare");

  if (screenShareNode) {
    screenShareNode.srcObject = null; // Prevent memory leak in Chrome
    screenShareNode.parentNode.removeChild(screenShareNode);
  }
};

Open the client.js file and add a condition upon receiving a streamRemoved event to handle the case when the stream.type is ScreenShare:

VoxeetSDK.conference.on("streamRemoved", (participant, stream) => {
  if (stream.type === "ScreenShare") {
    return removeScreenShareNode();
  }

  removeVideoNode(participant);
  removeParticipantNode(participant);
});