Skip to main content

Quickstart for React Hooks

Index#

  1. Create account on Video SDK
  2. Setup Server
  3. Structure of the Project
  4. Start Writing the Code

1. Create account on Video SDK#

Start Project at videosdk.live Create account on Video SDK

Navigate to the the start project button and register yourself either using Google Account or Github.

Prerequisites#

2. Setup Server#

A server will require to perform authentication via JWT token. We are going to use official Node JS server example.

  • Clone following repository and run the server.
$ git clone https://github.com/videosdk-live/videosdk-rtc-nodejs-sdk-example$ cd nodejs

Note: You can also find other backend language examples in the same repo.

Follow the Node JS Server Setup Guide to run the server.

3. Structure of the Project#

You can use react-scripts to generate project template or any other react boilerplate.

Create new project using create-react-app#

npx create-react-app videosdk-react-app-v1

This is how your project directory should look like

.โ”œโ”€โ”€ node_modulesโ”œโ”€โ”€ publicโ”œโ”€โ”€ .envโ”œโ”€โ”€ srcโ”‚ โ””โ”€โ”€ api.jsโ”‚ โ””โ”€โ”€ App.jsxโ”‚ โ””โ”€โ”€ index.cssโ”‚ โ””โ”€โ”€ index.jsxโ”œโ”€โ”€ package.json....

Configure Environment Variables#

Before writing the code, configure .env variables.

.env

REACT_APP_SERVER_URL="http://localhost:9000"

Note: For production environment, you have to host this server and need to change URL.

Install the official React JS package#

Before jumping to anything else, install videosdk react js sdk.

yarn add @videosdk.live/react-sdk

4.Start Writing the Code#

We will first setup API calls then after jump to writing the code.

Calling API to generate auth token and meetingId#

We will start writing the code with api.js. Before starting any meeting, you have to generate authentication token and meetingId

api.js

const API_BASE_URL = process.env.REACT_APP_SERVER_URL;
// API call to generate authentication tokenexport const getToken = async () => {  const res = await fetch(`${API_BASE_URL}/get-token`, {    method: "GET",  });
  const { token } = await res.json();  return token;};
// API call to create meetingexport const createMeeting = async ({ token }) => {  const res = await fetch(`${API_BASE_URL}/create-meeting`, {    method: "POST",    headers: { "Content-Type": "application/json" },    body: JSON.stringify({ token }),  });
  const { meetingId } = await res.json();  return meetingId;};

Start with App.jsx#

First of all, Let's setup token generation and meetingId logic before working on video calling view.

App Component

import logo from './logo.svg';import './App.css';import React, { useEffect, useRef, useState } from "react";import {  MeetingProvider,  MeetingConsumer,  useMeeting,  useParticipant,} from "@videosdk.live/react-sdk";import { getToken, validateMeeting, createMeeting } from "./api";
function MeetingGrid() {  return <h1>Meeting Grid</h1>}
function JoinScreen() {  return <h1>Join Screen</h1>}
function ParticipantView(props){  return <h1>Participant View</h1>}
function App() {  const [token, setToken] = useState(null);  const [meetingId, setMeetingId] = useState(null);
  const getMeetingAndToken = async () => {    const token = await getToken();    const meetingId = await createMeeting({ token });
    setToken(token);    setMeetingId(meetingId);  };
  useEffect(getMeetingAndToken, []);  return token && meetingId ? (    <MeetingProvider      config={{        meetingId,        micEnabled: true,        webcamEnabled: false,        name: "Participant Name",      }}      token={token}    >      <MeetingConsumer>        {() => <MeetingGrid />}      </MeetingConsumer>    </MeetingProvider>  ) : (    <JoinScreen />  );}
export default App;

React JS SDK provides two important hooks API:

  • useMeeting: Responsible to handle meeting environment.
  • useParticipant: Responsible to handle

Also, React Provider and Consumer to listen changes in meeting environment.

  • MeetingProvider: Meeting Provider is Context.Provider that allows consuming components to subscribe to meeting changes.
  • MeetingConsumer: Meeting Consumer is Context.Consumer that subscribes to meeting changes.

Implement Join Screen#

We will start with join screen where user can either create meeting or can join using meetingId.

It contains two simple features:

  1. Create New Meeting
  2. Join the meeting

JoinScreen Component

function JoinScreen() {  <div>    <input type="text" placeholder="Enter Meeting Id" onChange={(e) => {setMeetingId(e.target.value)}}  />    <button  onClick={getMeetingAndToken}>      Join    </button>    <button  onClick={getMeetingAndToken}>      Create Meeting    </button>  </div>}

Implementing Meeting Grid#

Meeting grid will include whole meeting interface. It will be responsible for:

  1. Turn On and Off Mic
  2. Turn On and Off WebCam
  3. Participant View
const {   join,    leave,     toggleMic,   toggleWebcam,   toggleScreenShare} = useMeeting();

Let's get started and implement it one by one. useMeeting hook will help you to perform join, leave, toggleMic etc.

Meeting Grid Component

// Helper function for participant loop.const chunk = (arr) => {  const newArr = [];  while (arr.length) newArr.push(arr.splice(0, 3));  return newArr;};
function MeetingGrid(props) {  const [joined, setJoined] = useState(false)  const {    join,     leave,      toggleMic,    toggleWebcam,    toggleScreenShare  } = useMeeting()  const { participants } = useMeeting();  const joinMeeting = () => {    setJoined(true)    join()  }  return (    <div>      <header>Meeting Id: {props.meetingId}</header>      {joined ?       (        <div >          <button  onClick={leave}>            Leave          </button>          <button  onClick={toggleMic}>            toggleMic          </button>          <button  onClick={toggleWebcam}>            toggleWebcam          </button>          <button  onClick={toggleScreenShare}>            toggleScreenShare          </button>         </div>      )       : (<button  onClick={joinMeeting}>        Join      </button>)}      <div        className="wrapper"      >        {chunk([...participants.keys()]).map((k) => (          <div className="box" key={k} style={{ display: "flex" }}>            {k.map((l) => (              <ParticipantView key={l} participantId={l} />            ))}          </div>        ))}      </div>          </div>  )}

Implementing Participant View#

To implement participant grid, we are going to use react-simple-flex-grid. It will be helpful to maintain video grid.

Let's first add this package.

yarn add react-simple-flex-grid

Import react-simple-flex-grid in App Component

import { Row, Col } from 'react-simple-flex-grid';import "react-simple-flex-grid/lib/main.css";

Participant view will include three major features:

  1. Enable/Disable WebCam
  2. Enable/Disable Mic
  3. Share your screen.

Let's explore each of it. Before starting it, we have to understand useRef of audio, video and screen share element

const webcamRef = useRef(null);const micRef = useRef(null);const screenShareRef = useRef(null);

Apart from that, useParticipant hook will help you to handle mic, webcam and screen share.

 const {    displayName,    webcamStream,    micStream,    screenShareStream,    webcamOn,    micOn,    screenShareOn  } = useParticipant(props.participantId);

After getting the stream, you can add track to using MediaStream API. For example, check out below code to add reference of webCam

 const mediaStream = new MediaStream(); mediaStream.addTrack(webcamStream.track);
 webcamRef.current.srcObject = mediaStream; webcamRef.current   .play()   .catch((error) =>     console.error("videoElem.current.play() failed", error));

After adding the reference in on loading state of component, you can

ParticipantView Component

function ParticipantView(props) {  const webcamRef = useRef(null);  const micRef = useRef(null);  const screenShareRef = useRef(null);
  const {    displayName,    webcamStream,    micStream,    screenShareStream,    webcamOn,    micOn,    screenShareOn  } = useParticipant(props.participantId);
  useEffect(() => {    if (webcamRef.current) {      if (webcamOn) {        const mediaStream = new MediaStream();        mediaStream.addTrack(webcamStream.track);
        webcamRef.current.srcObject = mediaStream;        webcamRef.current          .play()          .catch((error) =>            console.error("videoElem.current.play() failed", error)          );      } else {        webcamRef.current.srcObject = null;      }    }  }, [webcamStream, webcamOn]);
  useEffect(() => {    if (micRef.current) {      if (micOn) {        const mediaStream = new MediaStream();        mediaStream.addTrack(micStream.track);
        micRef.current.srcObject = mediaStream;        micRef.current          .play()          .catch((error) =>            console.error("videoElem.current.play() failed", error)          );      } else {        micRef.current.srcObject = null;      }    }  }, [micStream, micOn]);
  useEffect(() => {    if (screenShareRef.current) {      if (screenShareOn) {        const mediaStream = new MediaStream();        mediaStream.addTrack(screenShareStream.track);
        screenShareRef.current.srcObject = mediaStream;        screenShareRef.current          .play()          .catch((error) =>            console.error("videoElem.current.play() failed", error)          );      } else {        screenShareRef.current.srcObject = null;      }    }  }, [screenShareStream, screenShareOn]);

  return (    <div key={props.participantId} >      <audio ref={micRef} autoPlay />      {webcamRef ||  micOn ? (<div>      <h2>{displayName}</h2>      <video        height={"100%"}        width={"100%"}        ref={webcamRef}        autoPlay      />      </div>) : null }      {screenShareOn ? (      <div>        <h2>Screen Shared</h2>        <video          height={"100%"}          width={"100%"}          ref={screenShareRef}          autoPlay        />      </div>) : null }      <br/>      <span>Mic:{micOn ? "Yes": "No"}, Camera: {webcamOn ? "Yes" : "No"}, Screen Share: {screenShareOn ? "Yes" : "No"}</span>    </div>  );}

You can implement further features like cloud recording, chat, whiteboard, social media live etc by refereeing official guide of Video SDK

For more information, visit our official Guide