Participant Notification Sound

It’s a common practice to give users a sound indication that a participant has joined or left their call. Fortunately it’s very easy to do this since the SDK will fire events indicating that someone has joined or left a call. All we need to do is subscribe to these events.

But first, let’s implement a helper function that will play a sound for us. We’ll use the Audio constructor to create an off-screen HTMLAudioElement for each sound we want to play. We’ll cache these audio elements so they don’t have to be recreated each time we play a sound.

const audioCache = new Map<string, () => Promise<void>>();

async function playSoundFromUrl(url: string) {
  let doPlay = audioCache.get(url);

  if (!doPlay) {
    // Wait for an audio file to load
    const canPlayPromise = new Promise<HTMLAudioElement>((resolve) => {
      const audio = new Audio(url);
      audio.addEventListener("canplaythrough", () => resolve(audio), {
        once: true,
      });
    });

    doPlay = async () => {
      const audio = await canPlayPromise;
      await audio.play();
    };

    // Save to cache
    audioCache.set(url, doPlay);
  }

  await doPlay();
}

Now it’s just a matter of subscribing to the call.session_participant_joined and call.session_participant_left events. We can do this from a custom hook:

function useNotificationSounds() {
  const call = useCall();
  // We don't want to play the sound when the user joins themself
  const isSelf = useCallback(
    (userId: string) => userId === call?.currentUserId,
    [call],
  );

  useEffect(() => {
    if (!call) {
      return;
    }

    const unlistenJoin = call.on("call.session_participant_joined", (event) => {
      if (!isSelf(event.participant.user.id)) {
        playSoundFromUrl("joined.mp3");
      }
    });

    const unlistenLeft = call.on("call.session_participant_left", (event) => {
      if (!isSelf(event.participant.user.id)) {
        playSoundFromUrl("left.mp3");
      }
    });

    return () => {
      unlistenJoin();
      unlistenLeft();
    };
  }, [call, isSelf]);
}

And that’s all there is to it! Add this custom hook anywhere in a call UI (inside <StreamCall>), and you’ll get notification sounds when participants join and leave.

© Getstream.io, Inc. All Rights Reserved.