Participant visibility tracking

Depending on the UI layout of your call, some participants may not be visible on the screen at all times. This is especially true for large calls with many participants. We can optimize the performance and bandwidth usage of our SDK by only subscribing to video for participants that are visible on the screen or within a certain viewport.

To help you keep track of which participants are visible on the screen, our SDK provides a few helpers. Once you set up visibility tracking to a participant, the client can automatically subscribe and unsubscribe to the video and screen stream of the given participant.

Setup a visibility tracker

Any DOM element can be tracked for visibility. In a typical scenario, that would be the element that wraps the participant’s “box”. You can register a visibility tracker with the SDK by calling the call.trackElementVisibility method:

const myParticipantElement = document.getElementById("my-participant-element");

// Track the visibility of the participant's element
// you can use the returned function to stop tracking an element.
const untrack = call.trackElementVisibility(
  myParticipantElement,
  participant.sessionId,
  "videoTrack", // or 'screenShareTrack' if you want to track screen share visibility
);

Setup a viewport

In our context, a Viewport is a section/container on the screen that wraps participant’s video elements. Typically, this is a scrollable container. You can register a viewport with the SDK by calling the call.setViewport method:

const viewport = document.getElementById("my-participant-container");

// sets the viewport
// you can use the returned function to unset the viewport.
const unset = call.setViewport(viewport);

Access the visible participants

Every participant can have three visibility states for its video and screen share tracks:

  • VISIBLE - the track is visible on the screen
  • INVISIBLE - the track is not visible on the screen
  • UNKNOWN - the track’s visibility is unknown (e.g. the participant is not tracked)

Visibility state is available in the participant’s state:

import { VisibilityState } from "@stream-io/video-client";

call.state.participants.forEach((participant) => {
  const { viewportVisibilityState } = participant;

  // The participant's video visibility in the viewport
  switch (viewportVisibilityState.videoTrack) {
    case VisibilityState.VISIBLE:
      // The participant's video track is visible in the viewport
      break;
    case VisibilityState.INVISIBLE:
      // The participant's video track is not visible in the viewport
      break;
    case VisibilityState.UNKNOWN:
      // The participant's video track visibility in the viewport is unknown
      break;
  }

  // The participant's screen share visibility in the viewport
  switch (viewportVisibilityState.screenShareTrack) {
    case VisibilityState.VISIBLE:
      // The participant's screen share track is visible in the viewport
      break;
    case VisibilityState.INVISIBLE:
      // The participant's screen share track is not visible in the viewport
      break;
    case VisibilityState.UNKNOWN:
      // The participant's screen share track visibility in the viewport is unknown
      break;
  }
});
© Getstream.io, Inc. All Rights Reserved.