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.
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.
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.
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.
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.
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.