Quickstart for React Hooks
Index​
- Create account on Video SDK
- Setup Server
- Structure of the Project
- Start Writing the Code
1. Create account on Video SDK​
Start Project at videosdk.live
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 token
export 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 meeting
export 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:
- Create New Meeting
- 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:
- Turn On and Off Mic
- Turn On and Off WebCam
- 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:
- Enable/Disable WebCam
- Enable/Disable Mic
- 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
Got a Question? Ask us on discord