Walkthrough
React-Native

Migrating React Native SDK to v2 (2.x.x)

This guide will help you migrate your existing React Native SDK i.e. 0.x.x to the new 2.x.x version.

Installation

One of the biggest changes with 2.x.x versions of the SDKs is that the @huddle01/react-native package has been deprecated and now you can use the new and unified @huddle01/react package for building both web apps with React and mobile apps with React Native.

Install the latest version of the React SDK using the following command

pnpm i @huddle01/react@latest

Initialization

To initialize the SDK, you need to wrap your entire app inside HuddleProvider and pass projectId as a prop. After this, all methods used to interact with the SDK will be available to you via different hooks.

💡

You can retrieve your projectId from API Keys Page by just connecting your wallet.

app.tsx
import React from 'react'
import { Component } from 'react';
import {
  Text,
  SafeAreaView
} from 'react-native';
import { HuddleClient, HuddleProvider } from "@huddle01/react";
 
type Props = {};
 
const huddleClient = new HuddleClient({
  projectId: process.env.NEXT_PUBLIC_PROJECT_ID!,
  options: {
    // `activeSpeakers` will be most active `n` number of peers, by default it's 8
    activeSpeakers: {
      size: 12,
    },
  },
});
 
export default class App extends Component<Props> {
  render() {
    return (
      <HuddleProvider client={huddleClient}>
        <SafeAreaView>
          <Text>
            Welcome to React Native!
          </Text>
        </SafeAreaView>
       </HuddleProvider>
    );
  }
}

Room Creation

You need a roomId for joining a room, which you can get by calling the Create Room API. Make sure that you are calling this API from server side. You can create an API route in a separate Next.js web app or create an Express server.

pages/api/create-room.ts
import axios from 'axios';
import type { NextApiRequest, NextApiResponse } from 'next';
 
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
  try {
    const { data } = await axios.post(
      'https://api.huddle01.com/api/v1/create-room',
      {
        title: 'Huddle01 Meet',
      },
      {
        headers: {
          'Content-Type': 'application/json',
          'x-api-key': process.env.API_KEY as string,
        },
      }
    );
 
    res.status(200).json(data);
  } catch (error) {
    res.status(500).json(error);
  }
};
 
export default handler;

Authentication (Generating Access Token)

In 2.x.x version of SDK, you need an accessToken to join a room, without that you can't join a room using joinRoom method. To generate an accessToken you need to use our Server SDK

⚠️

Use Server SDK on server side only, don't use it on client side.

You can create an API route in a separate Next.js web app or create an Express server to generate accessToken.

pages/api/getAccessToken.ts
import type { NextApiRequest, NextApiResponse } from 'next';
import { AccessToken, Role } from '@huddle01/server-sdk/auth';
 
export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const { roomId } = req.query;
 
  if (!roomId) {
    return res.status(400).json({ error: 'roomId is required' });
  }
 
  const accessToken = new AccessToken({
    apiKey: process.env.API_KEY!,
    roomId: roomId as string,
    role: Role.HOST,
    permissions: {
      admin: true,
      canConsume: true,
      canProduce: true,
      canProduceSources: {
        cam: true,
        mic: true,
        screen: true,
      },
      canRecvData: true,
      canSendData: true,
      canUpdateMetadata: true,
    }
  });
 
  const token = await accessToken.toJwt();
 
  return res.status(200).json({ token });
}

Joining/Leaving Room

With our newer SDK i.e. 2.x.x, we have streamlined the process by eliminating the additional step of joining a lobby before entering a room. You can now directly join a room using joinRoom method returned from the useRoom hook. It requires one object parameter with two fields, roomId and token both of which have been generated in previous steps.

You can call the APIs which we have created in previous steps to get roomId and token.

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

Producing Audio/Video

In 2.x.x version of SDK, you don't need to call fetchVideoStream and produceVideo methods separately. You can just call enableVideo, which is returned from useLocalVideo hook. This will enable your camera and start producing your camera's video stream inside the room. Similarly, for audio as well you can just call enableAudio returned from useLocalAudio hook which will get your audio stream and start producing it inside the room.

💡

You can also share you screen and consume other peer's screen, to learn more refer to Screen Share.

app.tsx
  import {SafeAreaView, Button} from 'react-native';
  import { useLocalVideo, useLocalAudio, useLocalScreenShare } from '@huddle01/react/hooks';
 
  const App = () => {
    const { stream, enableVideo, disableVideo, isVideoOn } = useLocalVideo();
    const { stream, enableAudio, disableAudio, isAudioOn } = useLocalAudio();
    const { startScreenShare, stopScreenShare, shareStream } = useLocalScreenShare();
 
    return (
      <SafeAreaView>
        {/* Webcam */} 
        <Button
         title="Toggle Video"
          onPress={() => {
            isVideoOn ? disableVideo() : enableVideo()
          }}
        />
          
        {/* Mic */} 
        <Button 
          title="Toggle Audio"
          onPress={() => {
            isAudioOn ? disableAudio() : enableAudio();
          }}
        />
         
        {/* Screen Share */}
        <Button 
          title="Toggle Screen Share"
          onPress={() => {
            shareStream ? stopScreenShare() : startScreenShare();
          }}
        />
      </SafeAreaView>
    );
  };
 

Showing Remote Peers and Consuming their Audio/Video

In 2.x.x version of SDK, you have to use the usePeerIds hook to get an array of all the remote peers in the room. You can then use hooks such as useRemoteAudio, useRemoteVideo and useRemoteScreenShare for consuming their audio, video and screen-share streams.

💡

You can refer to usePeerIds, useRemoteAudio, and useRemoteVideo to learn more.

ShowPeers.tsx
  import { 
    usePeerIds, 
    useRemoteVideo, 
    useRemoteAudio, 
    useRemoteScreenShare 
  } from '@huddle01/react/hooks';
  import { Audio, Video } from '@huddle01/react/components';
  import { FC } from 'react';
  import {SafeAreaView, Button} from 'react-native';
 
  interface RemotePeerProps {
    peerId: string;
  }
 
  const RemotePeer: FC<RemotePeerProps> = ({ peerId }) => {
    
    const { stream: videoStream } = useRemoteVideo({ peerId });
    const { stream: audioStream } = useRemoteAudio({ peerId });
    const { videoStream: screenVideoStream, audioStream: screenAudioStream } = useRemoteScreenShare({ peerId });
  
    return (
      <SafeAreaView>
        {videoStream && <Video stream={videoStream}>}
        {audioStream && <Audio stream={audioStream}>}
        {screenVideoStream && <Video stream={screenVideoStream}>}
        {screenAudioStream && <Audio stream={screenAudioStream}>}
      </SafeAreaView>
    )
  }
  
  const ShowPeers = () => {
    const { peerIds } = usePeerIds();
 
    return (
      <SafeAreaView>
        {peerIds.map(peerId => {
          return <RemotePeer peerId={peerId}  />
        })}
      </SafeAreaView>
    )
  }
 
  export default ShowPeers;

Sending/Receiving Data

In 2.x.x version of SDK, you can send and receive data using the useDataMessage hook.

💡

You can also pass label while sending data, which will help you to identify the type of data while receiving.

const {
    sendData
  } = useDataMessage({
    onMessage(payload, from, label) {
        //received data message
        console.log(payload, from, label);
    };
  });
 
  sendData({
    to: '*',
    payload: "Hello World!",
    label: "chat"
  });

Happy Hacking 🎉

You can refer to the following sample apps build on Javascript SDK

Congratulations! If you have followed this guide till here, we hope that you have successfully migrated to 2.x.x

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.