DEV Community

Cover image for I built a video calling app in just 10 mins!
Riya Chudasama
Riya Chudasama

Posted on

I built a video calling app in just 10 mins!

Hey community!

In this blog, I am going to reveal about the secret behind how i created an audio video conferencing application in react in just 10 minutes! So are you ready? Let's dive in

cat typing

Few days back i was browsing the web in search of an SDK that offers video calling feature to integrate in my react application. That's when i came across VideoSDK.

Now you might be wondering there are so many SDKs available then why did i choose VideoSDK?

What Makes VideoSDK Exceptional for Audio and Video Conferencing?

  • Low Latency: VideoSDK delivers exceptional low latency. The lowest it can reach as low as 12 milliseconds and average latency can vary around less than 99 milliseconds end-to-end in optimal conditions.
  • Adaptive MultiStreaming: The platform automatically adjusts video quality based on your internet speed. Thus, your video stays smooth and clear, even if your network connection isn’t perfect..
  • Extensive Customization: VideoSDK allows developers to fully customize the user interface and features, enabling tailored experiences that align with specific application branding and functi onality.
  • Cross-Platform Compatibility: With support for web, mobile, and desktop applications, VideoSDK ensures users can connect easily across various devices, thus enhancing accessibility and usability.

Key Concepts :

Before you get your hands dirty with coding, it’s essential to understand the following core concepts:

  • MeetingProvider : It is fundamental component in VideoSDK react library that initializes the meeting context and allows you to share data related to meeting throughout your application.
  • MeetingConsumer : It is a component of VideoSDK React library that listen for the changes in the meeting state and re-render whenever data from MeetingProvider updates.
  • useMeeting Hook: Hook that provides functionalities such as joining, leaving, toggling mic/webcam, and sharing the screen.
  • useParticipant Hook: Allows managing and retrieving data of in dividual participants.

Here is the step by step process that i followed to integrate VideoSDK's audio video conferencing feature into my react application :

Prerequisites :

Before you get started , ensure you have the following prerequisites :

  1. VideoSDK Developer Account ( Not having one, follow VideoSDK Dashboard )

  2. Basic understanding of React & Hooks (useState, useRef, useEffect)

  3. Have Node and NPM installed on your device.

Step 1 : Setting Up Your React Environment

1. Create new React App :
 $ npx create-vite@latest videosdk-rtc-react-app --template react 
 $ cd videosdk-rtc-react-app
 $ npm install
Enter fullscreen mode Exit fullscreen mode
2. Install VideoSDK and dependencies
 $ npm install "@videosdk.live/react-sdk"

 //For the Participants Video
 $ npm install "react-player"
Enter fullscreen mode Exit fullscreen mode
3. Structure of the project
  root/
  ├── node_modules/
  ├── public/
  ├── src/
  │   ├── API.js
  │   ├── App.js
  │   ├── index.js
  │   ├── components/
  │   │   ├── Controls.js
  │   │   ├── JoinScreen.js
  │   │   ├── Container.js
  │   │   ├── ParticipantView.js
  ├── package.json
Enter fullscreen mode Exit fullscreen mode

Step 2 : Retrieving Your VideoSDK API Key

To create a new meeting , an API call will be required. You can either use temporary auth-token from user dashboard or go for the auth-Token generated by your servers. We would recommend the later.

Create a new file named API.js in the src directory and add the following code :

// Auth token we will use to generate a meeting and connect to it
export const authToken = "<Generated-from-dashbaord>";
// API call to create meeting
export const createMeeting = async ({ token }) => {
  const res = await fetch(`https://api.videosdk.live/v2/rooms`, {
    method: "POST",
    headers: {
      authorization: `${authToken}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({}),
  });
  //Destructuring the roomId from the response
  const { roomId } = await res.json();
  return roomId;
};
Enter fullscreen mode Exit fullscreen mode

Step 3 : Main App Component

import "./App.css";
import React, { useEffect, useMemo, useRef, useState } from "react";
import {
  MeetingProvider,
  MeetingConsumer,
  useMeeting,
  useParticipant,
} from "@videosdk.live/react-sdk";

import { authToken, createMeeting } from "./API";
import Container from "./components/Container";
import JoinScreen from "./components/JoinScreen";

function App() {
  const [meetingId, setMeetingId] = useState(null);

  //You have to get the MeetingId from the API created earlier
  const getMeetingAndToken = async (id) => {
    const meetingId =
      id == null ? await createMeeting({ token: authToken }) : id;
    setMeetingId(meetingId);
  };

  const onMeetingLeave = () => {
    setMeetingId(null);
  };

  return authToken && meetingId ? (
    <MeetingProvider
      config={{
        meetingId,
        micEnabled: true,
        webcamEnabled: true,
        name: "Riya Chudasama",
      }}
      token={authToken}
    >
      <Container meetingId={meetingId} onMeetingLeave={onMeetingLeave} />
    </MeetingProvider>
  ) : (
    <JoinScreen getMeetingAndToken={getMeetingAndToken} />
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Step 4 : Join Screen Component

JoinScreen is the first screen that will appear in the UI once you start your application. You can create a new meeting in this component or even enter an existing meeting with meetingId.

import { useState } from "react";

function JoinScreen({ getMeetingAndToken }) {
  const [meetingId, setMeetingId] = useState(null);

  const onClick = async () => {
    await getMeetingAndToken(meetingId);
  };
  return (
    <div>
      <input
        type="text"
        placeholder="Enter Meeting Id"
        onChange={(e) => {
          setMeetingId(e.target.value);
        }}
      />
      <button onClick={onClick}>Join</button>
      {" or "}
      <button onClick={onClick}>Create Meeting</button>
    </div>
  );
}

export default JoinScreen;
Enter fullscreen mode Exit fullscreen mode

Step 5 : Implement the Meeting Component

Next we will be diverted to Container page where meeting id along with Join button will be displayed. You will join the meeting once you click on the button.

Container.jsx

 import React, { useState } from "react";
 import { useMeeting, Constants } from "@videosdk.live/react-sdk";
 import ParticipantView from "./ParticipantView";
 import Controls from "./Controls";

 export default function Container(props) {
   const [joined, setJoined] = useState(null);

   //Get the method which will be used to join the meeting.
   //We will also get the participants list to display all participants
   const { join, participants, enableScreenShare, disableScreenShare } =
     useMeeting({
       //callback for when meeting is joined successfully
       onMeetingJoined: () => {
         setJoined("JOINED");
       },
       //callback for when meeting is left
       onMeetingLeft: () => {
         props.onMeetingLeave();
         setJoined(null);
       },
     });
   const joinMeeting = () => {
     setJoined("JOINING");
     join();
   };

   const handleStartScreenShare = () => {
     enableScreenShare(); // Start screen sharing
   };

   const handleStopScreenShare = () => {
     disableScreenShare(); // Stop screen sharing
   };

   return (
     <div className="container">
       <h3>Meeting Id: {props.meetingId}</h3>
       {joined && joined == "JOINED" ? (
         <div>
           <Controls
             onStartScreenShare={handleStartScreenShare}
             onStopScreenShare={handleStopScreenShare}
           />
           //For rendering all the participants in the meeting
           {[...participants.keys()].map((participantId) => (
             <ParticipantView
               participantId={participantId}
               key={participantId}
             />
           ))}
         </div>
       ) : joined && joined == "JOINING" ? (
         <p>Joining the meeting...</p>
       ) : (
         <button onClick={joinMeeting}>Join</button>
       )}
     </div>
   );
 }
Enter fullscreen mode Exit fullscreen mode

Controls.jsx

This component gives users access to control their webcam, microphones and allow them to leave the meeting.

 import React from "react";
 import { useMeeting } from "@videosdk.live/react-sdk";

 function Controls({ onStartScreenShare, onStopScreenShare }) {
   const { leave, toggleMic, toggleWebcam } = useMeeting();
   return (
     <div>
       <button onClick={() => leave()}>Leave</button>
       <button onClick={() => toggleMic()}>toggleMic</button>
       <button onClick={() => toggleWebcam()}>toggleWebcam</button>
       <button onClick={onStartScreenShare}>Start Screen Share</button>
       <button onClick={onStopScreenShare}>Stop Screen Share</button>
     </div>
   );
 }

 export default Controls;
Enter fullscreen mode Exit fullscreen mode

ParticipantView.jsx

 import React, { useEffect, useMemo, useRef } from "react";
 import { useParticipant } from "@videosdk.live/react-sdk";
 import ReactPlayer from "react-player";

 function ParticipantView(props) {
   const micRef = useRef(null);
   const {
     webcamStream,
     micStream,
     webcamOn,
     micOn,
     isLocal,
     displayName,
     screenShareStream,
   } = useParticipant(props.participantId);

   const videoStream = useMemo(() => {
     if (webcamOn && webcamStream) {
       const mediaStream = new MediaStream();
       mediaStream.addTrack(webcamStream.track);
       return mediaStream;
     }
   }, [webcamStream, webcamOn]);

   //Playing the audio in the <audio>
   useEffect(() => {
     if (micRef.current) {
       if (micOn && micStream) {
         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]);

   return (
     <div>
       <p>
         Participant: {displayName} | Webcam: {webcamOn ? "ON" : "OFF"} | Mic:{" "}
         {micOn ? "ON" : "OFF"}
       </p>
       <audio ref={micRef} autoPlay playsInline muted={isLocal} />
       {webcamOn && (
         <ReactPlayer
           //
           playsinline // extremely crucial prop
           pip={false}
           light={false}
           controls={false}
           muted={true}
           playing={true}
           //
           url={videoStream}
           //
           height={"300px"}
           width={"300px"}
           onError={(err) => {
             console.log(err, "participant video error");
           }}
         />
       )}

       {/* Render screen share stream if available */}
       {screenShareStream && (
         <ReactPlayer
           playsinline // extremely crucial prop
           pip={false}
           light={false}
           controls={false}
           muted={true} // You may want to adjust this based on your needs
           playing={true}
           url={screenShareStream} // Use the screen share stream here
           height={"300px"}
           width={"300px"}
           onError={(err) => {
             console.log(err, "screen share error");
           }}
         />
       )}
     </div>
   );
 }

 export default ParticipantView;
Enter fullscreen mode Exit fullscreen mode

Step 6 : Running the application

$ npm run dev
Enter fullscreen mode Exit fullscreen mode

Open localhost:3000 in your browser. Enter a meeting ID and join the meeting.

Congrats

Congrtulations! With just a few steps, we’ve created a basic meeting app using React and VideoSDK. From here, you can enhance your app by adding features like chat, recording, or breakout rooms. VideoSDK’s comprehensive documentation will guide you as you build advanced functionalities.

Happy coding :)

Top comments (0)