A Developer’s Intro to Huddle01 SDK and Ideas to Build

·

13 min read

Have you ever heard of a dRTC (decentralized real-time communication) protocol before? Well, this blog is entirely dedicated to developing audio and video apps by leveraging a dRTC protocol known as Huddle01.

What's dRTC ?

To address the limitations of WebRTC (Limited Scalability,Centralized Control,Lack of Trust & Incentive), a new solution emerges: Decentralized Real-Time Communication (dRTC). dRTC leverages power of peer-to-peer protocols to facilitate direct communication between users without relying on centralized servers. Unlike traditional communication systems, dRTC ensures transparency, security, and trust in the communication process by decentralizing control and ownership.

What makes Huddle01 special ?

By harnessing a decentralized architecture and routing data streams through a network of globally distributed, community-powered nodes, Huddle01’s dRTC network significantly reduces data transfer & compute costs, improves the quality of interactions and makes it more secure and private with end-to-end encryption. The community-powered nodes comprise of media nodes who provide bandwidth, orchestrators who allocate resources efficiently, and validators who validate transactions and secure the system.

How to build a real time communication apps using Huddle01? They provide us SDK's for various frameworks which we can leverage to build real-time communication apps.

SDK's availableDescription
JavaScriptoffers methods and event listeners
React JSoffers hooks, methods and event listeners
React Nativeoffers hooks, methods and event listeners
Flutteroffers methods and event listeners
Server Sideto perform protected admin actions on your server side

Before diving into the SDK's let's familiarize with few terminologies related to Huddle01 SDK.

Room - It contains all the participants and their media streams. Each room is identified by a unique roomID that is generated when you create a room.

Peer - A peer is a participant inside a room. It is an object containing all the media streams of a participant.

MediaStream - The MediaStream interface represents a stream of media content.

Local - Once you join a room, all operations related to your own Peer object inside a room are represented by the keyword local.

Remote - All other peers in the same room as you are represented by the keyword remote.

If you're only interested in demo app code, feel free to skip the next two sections. In the following two sections, I provide detailed explanations of the Huddle01 SDKs and iFrames

Huddle01 SDK deep dive

💡
First create an API key by heading over this page . It will be used to authorize you to access Huddle01 infrastructure.

Javascript SDK :

Walkthrough :

  • Installation :

    1. By using script tag

      <script src="https://unpkg.com/@huddle01/web-core@umd/dist/index.global.js"></script>

    2. By using npm (other package managers available)

      npm install @huddle01/web-core

  • Available methods :

  • Methods usage example :

    1. IIFE/UMD

       <script src="https://unpkg.com/@huddle01/web-core@umd/dist/index.global.js"></script>
       <script>
       let client;
      
       const init = async () => {
         client = new HuddleWebCore.HuddleClient({
           projectId: "YOUR_PROJECT_ID",
           },
         });
         const room = await client.joinRoom({
           roomId: "YOUR_ROOM_ID",
           token: "YOUR_ACCESS_TOKEN",
         });
       };
       </script>
      
    2. ESM/CommonJS

       import { HuddleClient } from '@huddle01/web-core';
       const huddleClient = new HuddleClient({
         projectId: "YOUR_PROJECT_ID"
       })
      
       huddleClient.joinRoom({
           roomId: "YOUR_ROOM_ID",
           token: "YOUR_ACCESS_TOKEN"
       });
      
  • Example app : https://docs.huddle01.com/docs/Javascript/example

React SDK

The Huddle01 React SDK offers hooks, methods and event listeners. The SDK contains two components (Audio and Video) which you can leverage to play audio stream and to show video stream respectively.

Available Hooks :

WalkThrough :

  • Installation

    npm install @huddle01/react

    or

    yarn add @huddle01/react

  • Initializing the SDK

      import { HuddleProvider, HuddleClient } from '@huddle01/react';
    
      const huddleClient = new HuddleClient({
        projectId: env.NEXT_PUBLIC_PROJECT_ID,
        options: {
          activeSpeakers: {
            size: 8,
          },
        },
      });
    
      ...
      <HuddleProvider client={huddleClient}>
        <App />
      </HuddleProvider>
      ...
    
  • Joining a Room

      import { useRoom } from '@huddle01/react/hooks';
    
      const { joinRoom } = useRoom({
         onJoin: () => {
           console.log('Joined room');
         }
      });
      // join room 
      joinRoom({
         roomId: "YOUR_ROOM_ID",
         token: "YOUR_TOKEN"
      });
    

React Native :

The same React SDK can be used to build mobile applications using React Native. It is just that you will have to install few other dependent packages react-native-get-random-values and react-native-webrtc for the proper functioning Huddle01 React SDK.

Walkthrough :

💡
Make sure to add camera and mic permissions to your AndroidManifest.xml file (for Android) and Info.plist file (for iOS)
  • Installation

    pnpm i @huddle01/react @huddle01/server-sdk react-native-get-random-values react-native-webrtc or

    npm i @huddle01/react @huddle01/server-sdk react-native-get-random-values react-native-webrtc or

    yarn add @huddle01/react @huddle01/server-sdk react-native-get-random-values react-native-webrtc

  • Configuring the SDK (add this at top of index.js)

      import { AppRegistry } from 'react-native';
      import 'react-native-get-random-values';
      import { registerGlobals } from 'react-native-webrtc';
      import App from './App';
    
      registerGlobals();
    
      AppRegistry.registerComponent(appName, () => App);
    
  • Initialize the project

      import { HuddleClient, HuddleProvider } from '@huddle01/react';
    
      const huddleClient = new HuddleClient({
        projectId: env.NEXT_PUBLIC_PROJECT_ID,
        options: {
          activeSpeakers: {
            size: 8,
          },
        },
      });
    
      const Parent = () => {
        return (
          <HuddleProvider key="huddle01-provider" client={huddleClient}>
            <App />
          </HuddleProvider>
        );
      };
    
  • Joining and Leaving the room

      import { useRoom } from '@huddle01/react/dist/hooks';
      import {Button, View} from 'react-native';
    
      const App = () => {
        const { joinRoom, leaveRoom } = useRoom({
          onJoin: () => {
            console.log('Joined the room');
          },
          onLeave: () => {
            console.log('Left the room');
          },
        });
    
        return (
          <View>
          <Button
            title="Join Room"
            onPress={() => {
              joinRoom({
                roomId: 'YOUR_ROOM_ID',
                token: 'YOUR_ACCESS_TOKEN'
              })
            }}
            />
    
            <Button title=" Leave Room" onPress={leaveRoom} />
    
          </View>
        );
      };
    

Flutter SDK :

Walkthrough :

  • Installation

      flutter pub add huddle01_flutter_client
    
  • Permissions Setup

    Android (inside AndroidManifest.xml)

      <uses-feature android:name="android.hardware.camera"/>
      <uses-feature android:name="android.hardware.camera.autofocus"/>
      <uses-permission android:name="android.permission.CAMERA"/>
      <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
      <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
      <uses-permission android:name="android.permission.RECORD_AUDIO"/>
      <uses-permission android:name="android.permission.INTERNET"/>
      <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
      <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
      <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
      <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    

    Ios (inside Info.plist)

      <key>NSMicrophoneUsageDescription</key>
      <string>{YOUR_SDK_APP} wants to use your microphone</string>
      <key>NSCameraUsageDescription</key>
      <string>{YOUR_SDK_APP} wants to use your camera</string>
      <key>NSLocalNetworkUsageDescription</key>
      <string>{YOUR_SDK_APP} App wants to use your local network</string>
      <key>NSBluetoothAlwaysUsageDescription</key>
      <string>{YOUR_SDK_APP} needs access to bluetooth to connect to nearby devices.</string>
    
  • Initialization

      import 'package:huddle01_flutter_client/huddle01_flutter_client.dart';
    
      String projectId = 'YOUR-PROJECT-ID';
      String roomId = 'YOUR-ROOM-ID';
    
      // Initialize your huddleClient 
      HuddleClient huddleClient = HuddleClient(projectId);
    

Server SDK :

The Server SDK helps you to perform server-side operation such as generating Access Token, calling APIs such as Create Room, Live Meetings, etc, starting and stopping recording and livestream, and send messages from server-side.

Available API functions

Walkthrough :

  • Installation

      npm install @huddle01/server-sdk@latest
    
  • Generating Access Token

      const accessToken = new AccessToken({
        apiKey: "YOUR_API_KEY",
        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: {
            walletAddress: "user.eth", // custom wallet adderss
          },
        },
      });
    
      const token = accessToken.toJwt();
    

iFrames

Are you lazy to write mode lines of code or you are looking for an easy way to integrate your website with Huddle? Then iFrames are the best available solution for you. You can also customize these iFrame to match your website's branding and ensure a seamless user experience for your visitors.

Huddle01 provides iFrame for both Vanilla and React web applications.

Vanilla JS iFrame :

Walkthrough :

  • CDN

      <script src="https://unpkg.com/@huddle01/iframe@0.0.11/dist/huddle01-iframe.umd.min.js"></script>
    
  • iFrame

      <iframe
        id="huddle01-iframe"
        src="https://iframe.huddle01.com/some-room"
        name="myiFrame"
        scrolling="no"
        height="90%"
        width="90%"
        allowFullScreen
        allow="camera; microphone; clipboard-read; clipboard-write; display-capture"
      ></iframe>
    
  • Color Customization

      // Light Theme
      HIframe.iframeApi.setTheme(lightTheme)
    
      // Dark Theme
      HIframe.iframeApi.setTheme(darkTheme)
    
      // Custom Colors
      HIframe.iframeApi.setTheme({
        iconColor: '#94A3B8',
        textColor: 'red',
        borderColor: '#1C1E24',
        brandColor: 'blue',
        interfaceColor: '#181A20',
        onBrandColor: '#ffffff',
      })
    

React iFrame :

Walkthrough (for tsx):

  • Installation

      npm install @huddle01/iframe
    
  • Usage

      import { HuddleIframe } from "@huddle01/iframe";
    
      function App() {
          return (
              <div>
                  <HuddleIframe roomUrl="https://iframe.huddle01.com/YOUR_ROOM_ID" className="w-full aspect-video" />
              </div>
          );
      }
    
  • Color Customisation

      import { darkTheme, lightTheme } from "@huddle01/iframe/types";
      import { HuddleIframe } from "@huddle01/iframe";
    
      // Light Theme
      <HuddleIframe
              roomUrl="https://iframe.huddle01.com"
              theme={lightTheme}
      />
    
      // Dark Theme
      <HuddleIframe
              roomUrl="https://iframe.huddle01.com"
              theme={darkTheme}
      />
    
      // Custom Colors
      <HuddleIframe
              roomUrl="https://iframe.huddle01.com"
              theme={{
                  iconColor: '#94A3B8',
                textColor: 'red',
                borderColor: '#1C1E24',
                brandColor: 'blue',
                  interfaceColor: '#181A20',
                  onBrandColor: '#ffffff',
              }}
      />
    

Building a sample Meeting Room: A Practical SDK Usage Example

In this section we are going to build an real time video meet room using Huddle01 React SDK . The below diagram gives a brief of what our app is going to do.

By using the app a person can enter a room if he has valid RoomID or create his own room by generating a new RoomID. inside this room they can stream live video and view other participants live stream.

Pre-requisites :

  1. Node JS

  2. Npm installed

  3. Go the https://docs.huddle01.com/docs/api-keys and generate you own api key and project id.

Setup :

npx create-next-app app_name # choose ts, tailwind and app router

# after creating the nextjs app install huddle package
cd app_name
npm i @huddle01/react @huddle01/server-sdk

code deep dive :

Go to layout.tsx and update it to the below code

'use client'

import 'tailwindcss/tailwind.css'

import { HuddleClient, HuddleProvider } from "@huddle01/react";
import React from "react";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {

  const huddleClient = new HuddleClient({
    projectId: ""!, // replace with you project id
  });

  return (
    <html lang="en">
      <body>
        <HuddleProvider client={huddleClient}>
          {children}
        </HuddleProvider>
      </body>
    </html>
  );
}

let's create a new roomCreate.ts file where we will write the logic to generate room id.

"use server";

export const createRoom = async () => {
  const response = await fetch("https://api.huddle01.com/api/v1/create-room", {
    method: "POST",
    body: JSON.stringify({
      title: "Creator Room", // Room name
    }),
    headers: {
      "Content-type": "application/json",
      "x-api-key": ""!, // use you api key
    },
    cache: "no-cache",
  });

  const data = await response.json();
  const roomId = data.data.roomId;
  return roomId;
};

This code snippet showcases how to create a room using a server-side SDK. an asynchronous function named createRoom is defined to handle the room creation process. The request payload includes a JSON object specifying the room title. Upon receiving the response, it is parsed as JSON, and the room ID is extracted from the returned data. Ultimately, the room ID is then returned from the function.

Next open page.tsx file

Add the necessary imports at the top

'use client'
import React, { useState } from 'react';
import { AccessToken, Role } from "@huddle01/server-sdk/auth";
import { createRoom } from "./roomCreate";
import { useRoom, useLocalVideo, usePeerIds, useRemoteVideo } from '@huddle01/react/hooks';
import { Video } from '@huddle01/react/components';

Add these hooks inside you root functional component. useRoom hook will be used to join or leave the room . useLocalVideo will be used to stream your video. usePeerIds hook will get you the list of people in the room which we will use to fetch and display their video streams.

const { joinRoom, leaveRoom } = useRoom({
    onJoin: () => { console.log('Joined the room'); },
    onLeave: () => { console.log('Left the room'); },
  });

  const { enableVideo, disableVideo, isVideoOn } = useLocalVideo();
  let { peerIds } = usePeerIds();

Now let's write logic for access token which will be used to authorize us into to room that we want to join.

async function genAccessToken(roomId: string, roles: Role) {
    const accessToken = new AccessToken({
      apiKey: ""!, // use your own api key
      roomId: roomId,
      role: roles,
      permissions: {
        admin: true,
        canConsume: true,
        canProduce: true,
        canProduceSources: {
          cam: true,
          mic: true,
          screen: true,
        },
        canRecvData: true,
        canSendData: true,
        canUpdateMetadata: true,
      }
    });

    try {
      const token = await accessToken.toJwt();
      console.log(token);
      setToken(token);
    } catch (error) {
      console.error("Error occurred while getting token:", error);
    }
  }

Let's write the logic to join the room.

async function joinAsHost() {
    await genAccessToken(inputValue, Role.HOST);
    console.log("Joining as host...");
    await joinRoom({
      roomId: inputValue,
      token: token
    });
  }

This function helps us the join the room as a host if you want to join as co-host , bot, participant, you just have to change the parameter that we are passing into genAccessToken function

In the below code, RemotePeer is a function component that renders a Video component based on the peerId prop it receives. It utilizes the useRemoteVideo hook to fetch the video stream associated with the provided peerId. If the video stream exists, it displays the video; otherwise, it displays nothing.

interface RemotePeerProps {
  peerId: string;
}

const RemotePeer: React.FC<RemotePeerProps> = ({ peerId }) => {
  const { stream: videoStream } = useRemoteVideo({ peerId });

  return (
    <div>
      {videoStream && <Video stream={videoStream}></Video>}
    </div>
  );
}

copy paste this jsx part

<div className="bg-gradient-to-b from-gray-200 to-gray-400 min-h-screen flex items-center justify-center">
  <div className="flex justify-between w-full max-w-screen-lg">
    <div className="flex flex-col items-start space-y-4">
      <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" onClick={genRoomId}>Generate Room ID</button>
      <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" onClick={() => console.log("Room ID:", roomId)}>Show Room ID</button>
      <input
        type="text"
        value={inputValue}
        onChange={handleInputChange}
        className="border rounded px-2 py-1"
        placeholder="Enter Room ID"
      />
      <div className="flex space-x-4">
        <button className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded" onClick={joinAsHost}>Join as Host</button>
        <button className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded" onClick={joinAsCoHost}>Join as Co-host</button>
      </div>
      <button className={`bg-${isVideoOn ? 'red' : 'green'}-500 hover:bg-${isVideoOn ? 'red' : 'green'}-700 text-white font-bold py-2 px-4 rounded`} onClick={() => (isVideoOn ? disableVideo() : enableVideo())}>
        {isVideoOn ? 'Disable Video' : 'Enable Video'}
      </button>
      <button className="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded" onClick={leaveTheRoom}>Leave Room</button>
    </div>
    <div className="flex flex-wrap justify-center">
      {peerIds != null && peerIds.length > 0 ? (
        peerIds.map(peerId => (
          <RemotePeer peerId={peerId}  />
        ))
      ) : (
        <div className="w-48 h-48 flex items-center justify-center bg-gray-200">No videos turned on</div>
      )}
    </div>
  </div>
</div>

Running the app :

If you are unable to compile the code pieces explained above into your own recipe, Don't worry you can clone it from my github repo. Then open you terminal and type

npm run dev

Output :

Generate a RoomID by clicking the Generate Room ID button. It will be displayed in the console. copy paste the id into the text field and click join as host or Co-host to join the room

Similarly open the file another window and join the room by copy pasting the roomID that was previously generated. Now we have 2 people in the room (isn't that cool !!).

Trust me , I'm not scamming you . Try pressing enable video button from one tab and navigate to the other tab to check if the video is being streamed or not.

The beauty is that anybody can join our room if they have our room id .

💡
This app is just a simple demo usage of Huddle01 React SDK to show how easy it is to integrate. It is neither a production grade app nor tested for vulnerabilities.

Huddle Guides

It's common for developers to search for examples to gain a better understanding of how functions defined in the SDK work. What's cool about the Huddle team is that they have already provided us with a bunch of guides to get started.

Link to Huddle Guides documentation - https://docs.huddle01.com/docs/guides

Innovative Applications Empowered by Huddle01

1.Meet With Wallet: Streamlined Scheduling for Web3

  • Meet With Wallet is a scheduling manager redefined for Web3. Take control of your time, your privacy, your rules.

2. Buttrfly: Redefining Social Connections with Audio

  • A Web3 Social Explorer build on lens protocol. Which uses Huddle01 audio spaces to deliver sounds .

3. EtherMail: Secure Communication Evolved

  • EtherMail is building the bridge between Web2 & Web3 via email, bringing full inbox ownership, control, and sovereignty back to users. They are the first email solution setting the standard for anonymous and encrypted wallet-to-wallet communication.

other popular builds Soclly, SyncX, Pixelmen, PeerCode, Studio01, Blinkr

Innovative Ideas to build using Huddle01

  1. Token Gated Meeting Apps :

    Build a meeting application that allows only a particular token holders to enter, which will be useful for NFT projects.

  2. Cross-Chain chatting apps :

    Huddle provides you with audio, video and message sending features. Then what stops you from building a real-time communication app that can operate by logging users through wallet and ensure more user privacy?

  3. Online Event Hosting :

    Build an app to conduct online workshops .

  4. Business / Healthcare Tool :

    Build an app which can be used to host secure & private business meetings or online doctor - patient appointments.

  5. AI - Integration :

    Am I crazy ? Every crazy ideas leads to a crazy result. You can try building one-to-one meeting apps where the other user is an AI / Ml model. Integrate the chat messages with a GPT or your own trained model to generate reply and add Speech Recognition Model to reply for audio messages.

Resources and References :