Walkthrough

Building a Vanilla App with Huddle01

💡

We have upgraded our SDK to v2 (2.x.x). For the previous stable release, please visit here

Walkthrough

The following guide explains how you can integrate audio/video into your application seamlessly using the Huddle01 vanilla JS SDK.

Install @huddle01/web-core package

To power your Vanilla JS App with audio/video communication using Huddle01.

pnpm i @huddle01/web-core

Initialization of project

Head over to API Keys Page and connect your wallet to get your project credentials:

  • API Key
  • projectId

Once done, initialize huddleClient with the following code snippet.

client.js
import { HuddleClient } from '@huddle01/web-core';
 
export const client = new HuddleClient({
  projectId: 'TxG-OolMwGeCoZPzX660e65wwuU2MP83',
});

Generating the Access Token

Once the client has been initialized, Room Id can be generated using the Create Room API

Access Token can be generated using Server-SDK. Make sure you use Server-SDK from server side only, don't call it from client side. We have created a token simulator (opens in a new tab) which you can use to generate room and access token. You can create your own server where you can generate the access token using the following code snippet.

server.js
  
  import { AccessToken, Role } from '@huddle01/server-sdk/auth';
 
  const generateAccessToken = async () => {
   const accessToken = new AccessToken({
        apiKey,
        roomId: "YOUR_ROOM_ID",
        role:  Role.HOST,
        permissions: {
          admin: true,
          canConsume: true,
          canProduce: true,
          canProduceSources: {
            cam: true,
            mic: true,
            screen: true,
          },
          canRecvData: true,
          canSendData: true,
          canUpdateMetadata: true,
        },
        options: {
          metadata: { 
             // you can add any custom attributes here which you want to associate with the user
            walletAddress: "vrajdesai.eth"
          },
        },
    });
  const token = await accessToken.toJwt();
  return token;
  }

Joining and leaving the room

The joinRoom() method can be called to enter the room. To leave that respective room you can call the leaveRoom() method.

Clicking on the JOIN_ROOM button, will make the user join the room and will allow them to send/receive media and data with other participants.

app.js
 
  document.getElementById('joinRoom').onclick = async () => {
    // you can use roomId and accessToken which we have generated in the above steps
    await huddleClient.joinRoom({
      roomId: "YOUR_ROOM_ID",
      token: "YOUR_ACCESS_TOKEN"
    });
  };
 
  document.getElementById('leaveRoom').onclick = async () => {
      await huddleClient.leaveRoom();
  };
 

Enabling and Disabling Audio, Video and Screen Share.

The following code snippet shows how you can enable/disable audio, video and screen share.

handleStream.js
import { client } from './client';
 
// This function will enable or disable audio stream
export function handleAudioStream(element) {
  element.addEventListener("click", async () => {
    // Reference to the button to enable/disable audio
    const audioRef = document.querySelector("#audio");
    // If audio stream is disabled, then enable it
    if (audioRef.textContent == "Disable Audio") {
      // This will disable the audio stream and other participants will not be able to hear you
      await client.localPeer.disableAudio();
      audioRef.textContent = "Enable Audio";
    } else {
      // This will enable the audio stream and other participants will be able to hear you
      await client.localPeer.enableAudio();
      audioRef.textContent = "Disable Audio";
    }
  });
}
 
// This function will enable or disable video stream
export function handleVideoStream(element) {
  element.addEventListener('click', async () => {
 
    // Reference to the button to enable/disable video
    const videoRef = document.querySelector('#videoRef');
 
    // If video stream is already enabled, then disable it
    if (videoRef.srcObject) {
      client.localPeer.disableVideo();
      videoRef.srcObject = null;
      document.querySelector('#video').textContent = 'Enable Video';
      return;
    }
 
    // This will fetch video stream and return MediaStream 
    const stream = await client.localPeer.enableVideo();
 
    // This will set the stream to the video element
    videoRef.srcObject = stream;
    videoRef.onloadedmetadata = async () => {
      try {
        await videoRef.play();
        document.querySelector('#video').textContent = 'Disable Video';
      } catch (error) {
        console.error(error);
      }
    };
  });
}
 
// This function will enable or disable screen share
export function handleScreenStream(element) {
  element.addEventListener('click', async () => {
 
    // Reference to the button to enable/disable screen share
    const screenRef = document.querySelector('#screenRef');
 
    // If screen share is already enabled, then disable it
    if (screenRef.srcObject) {
      client.localPeer.stopScreenShare();
      screenRef.srcObject = null;
      document.querySelector('#screen').textContent = 'Share Screen';
      return;
    }
 
    // This will fetch screen share stream and return MediaStream
    const stream = await client.localPeer.startScreenShare();
 
    // This will set the stream to the video element
    screenRef.srcObject = stream;
    screenRef.onloadedmetadata = async () => {
      try {
        await screenRef.play();
        document.querySelector('#screen').textContent = 'Stop Sharing';
      } catch (error) {
        console.error(error);
      }
    };
  });
}
 

Show remote peers in the room

We have to listen to two events stream-added and stream-closed from room to add and remove remote peers stream.

handleEvents.js
import { client } from "./client";
 
// This function needs to be called in app.js file
export function handleEvents() {
 
  // This event will be triggered when a new stream is added to the room
  client.room.on("stream-added", ({ peerId, label }) => {
    const container = document.querySelector("#remotePeers");
 
    // Create a new video element to show the remote stream
    let mediaRef = document.createElement("video");
 
    // If the stream is audio, then create audio element
    if (label == "audio") {
      mediaRef = document.createElement("audio");
    }
 
    // Get the track of remote peer from the room by getting the remote peer's consumer
    const remoteTrack = client.room
      .getRemotePeerById(peerId)
      ?.getConsumer(label)?.track;
 
    // Create a new media stream from the remote track and set it to the media element
    mediaRef.srcObject = new MediaStream([remoteTrack]);
    mediaRef.id = `${peerId}-${label}`;
    mediaRef.autoplay = true;
 
    // If the stream is video, then mute it
    if (label == "video") {
      mediaRef.muted = true;
    }
    mediaRef.className = "border-2 rounded-xl border-white-400 aspect-video";
    container.appendChild(mediaRef);
  });
 
  // This event will be triggered when a stream is closed in the room
  client.room.on("stream-closed", ({ peerId, label }) => {
    // Get the reference of media element    
    const mediaRef = document.querySelector(`#${peerId}-${label}`);
    // Stop the track and remove the media element
    mediaRef.srcObject.getTracks().forEach((track) => track.stop());
    mediaRef.srcObject = null;
    mediaRef.remove();
  });
}

You're all set! Happy Hacking! 🎉

Full code of this walkthrough can be found here (opens in a new tab). For more information, please refer to the SDK Reference.

Audio/Video Infrastructure designed for developers to empower them to ship simple yet powerful Audio/Video Apps.
support
company
Copyright © 2024 Graphene 01, Inc. All Rights Reserved.