100ms Logo

100ms

Docs

Search docs
/

Overview

It all comes down to this. All the setup so far has been done so that we can show live streaming video in our beautiful apps.

  1. First, you need to get all the peers in the room. You can use the selectPeers selector for this.

  2. Next, you'll need to have a reference to a video element. You must add the attributes as present below.

<video autoplay muted playsinline />
  1. You can then iterate over all the peers, and call the attachVideo function in hmsActions to render the video.
hmsActions.attachVideo(videoTrack.id, videoElement);

The videos will now be rendered & start playing on your screen. 🥳

In case you want to render local peer and remote peers separately, you can use the selectors - selectLocalPeer and selectRemotePeers.

Detach video to conserve bandwidth and cleanup elements

You can call detachVideo on the hmsActions to unsubscribe a track and not fetch it's data. This can be done for example when a video goes out of view. This should also be called when the component is going to be unmounted for proper cleanups of the video elements.

hmsActions.detachVideo(videoTrack.id, videoElement);

When to attach/detach videos

We need to re-attach video when it's in view after every:

  1. Unmute(when track.enable is true)
  2. Plugin is added/removed(for example, enable/disable virtual background)
  3. Camera/device change(track.deviceId is changed)

You can achieve all this by using the selectVideoTrackByID selector and the aforementioned hmsActions.attachVideo and hmsActions.detachVideo functions.

// assuming you have peer object and video element // complete code snippet below hmsStore.subscribe((track) => { if (!track) { return; } if (track?.enabled) { hmsActions.attachVideo(track.id, videoElement); } else { hmsActions.detachVideo(track.id, videoElement); } }, selectVideoTrackByID(peer.videoTrack));

Note that if you're using the useVideo hook from react-sdk this is already being taken care of.

Example Snippet

import { hmsActions } from './hms'; const peersContainer = document.getElementById('peers-container'); // store peer IDs already rendered to avoid re-render on mute/unmute const renderedPeerIDs = new Set(); // render a single peer video tile function renderPeer(peer) { const peerTileDiv = document.createElement('div'); // you can either get an existing video element or create a new one. const videoElement = document.createElement('video'); const peerTileName = document.createElement('div'); videoElement.autoplay = true; videoElement.muted = true; videoElement.playsinline = true; peerTileName.textContent = peer.name; hmsStore.subscribe((track) => { if (!track) { return; } if (track.enabled) { hmsActions.attachVideo(track.id, videoElement); } else { hmsActions.detachVideo(track.id, videoElement); } }, selectVideoTrackByID(peer.videoTrack)); peerTileDiv.append(videoElement); peerTileDiv.append(peerTileName); renderedPeerIDs.add(peer.id); return peerTileDiv; } // display a tile for each peer in the peer list function renderPeers(peers) { peersContainer = document.getElementById('peers-container'); peers.forEach((peer) => { if (!renderedPeerIDs.has(peer.id) && peer.videoTrack) { console.log( `rendering video for peer - ${peer.name}, roleName - ${peer.roleName}, isLocal- ${peer.isLocal}` ); peersContainer.append(renderVideo(peer)); } }); } // subscribe to the peers, so render is called whenever there is a change like peer join and leave hmsStore.subscribe(renderPeers, selectPeers);

Have a suggestion? Recommend changes ->

Was this helpful?

1234