How to Integrate Screen Share Feature in React JS Video Call App?
Tags: react, javascript, webdev
Published: 2024-04-17 11:25:40

---
title: How to Integrate Screen Share Feature in React JS Video Call App?
published: true
date: 2024-04-16 08:14:22 UTC
tags: react, javascript, webdev
canonical_url: https://www.videosdk.live/blog/integrate-screen-share-in-react-js
---

## 📌 Introduction
 ![How to Integrate Screen Share Feature in React JS Video Call App?](https://assets.videosdk.live/static-assets/ghost/2024/04/Screen-Share-React.png)

Integrating a screen share feature into your [React JS video call app](https://www.videosdk.live/blog/react-js-video-calling) can enhance collaboration and productivity. With this feature, users can seamlessly share their screens during calls, facilitating real-time presentations, demonstrations, and discussions. Begin by implementing a reliable screen-capturing mechanism using libraries like MediaDevices API or WebRTC. Design a user-friendly interface allowing users to initiate and stop screen sharing effortlessly.

**Benefits of Screen Share Feature:**

1. **Enhanced Collaboration** : Users can share their screens to demonstrate concepts, collaborate on projects, or provide real-time assistance, fostering better teamwork.
2. **Improved Communication** : Visual aids enhance communication by allowing users to illustrate ideas, share documents, or present slideshows during video calls.
3. **Increased Productivity** : Screen sharing reduces the need for separate meetings or lengthy explanations, leading to faster decision-making and task completion.
4. **Remote Work Facilitation** : Facilitates remote work by enabling virtual presentations, training sessions, and remote troubleshooting.
5. **Seamless Integration** : Integrating screen share seamlessly into your React JS app enhances its functionality, making it a comprehensive communication tool.

**Use Cases Screen Share Feature:**

1. **Remote Work** : Employees can conduct virtual meetings, share progress reports, and collaborate on documents or presentations from anywhere.
2. **Online Education** : Teachers can deliver interactive lessons, share educational resources, and provide one-on-one assistance to students through screen sharing.
3. **Customer Support** : Support agents can guide customers through troubleshooting steps, demonstrate product features, or assist with software setup via screen sharing.
4. **Team Collaboration** : Team members can brainstorm ideas, review designs, or collaborate on code by sharing their screens during video calls.
5. **Sales Demos** : Sales professionals can deliver persuasive product demonstrations, share sales decks, and answer client questions in real-time using screen sharing.

By the time you reach the end of this exhaustive guide, you'll be equipped with a fully-fledged React video call application that not only facilitates communication but also empowers users to collaborate with unparalleled efficiency. Say goodbye to mundane meetings and hello to a new era of dynamic collaboration!

## 🚀 Getting Started with VideoSDK

To take advantage of the chat functionality, we must use the capabilities that the VideoSDK offers. Before diving into the implementation steps, let's ensure you complete the necessary prerequisites.

### Create a VideoSDK Account

Go to your [VideoSDK dashboard](https://www.videosdk.live/signup?utm_source=organicseo&utm_medium=devto&utm_campaign=screen_share_react_js) and sign up if you don't have an account. This account gives you access to the required Video SDK token, which acts as an authentication key that allows your application to interact with VideoSDK functionality.

### Generate your Auth Token

Visit your VideoSDK dashboard and navigate to the "API Key" section to generate your auth token. This token is crucial in authorizing your application to use VideoSDK features.

For a more visual understanding of the account creation and token generation process, consider referring to the [provided tutorial](https://docs.videosdk.live/android/guide/video-and-audio-calling-api-sdk/authentication-and-token#1-generating-token-from-dashboard).

### Prerequisites and Setup

Before proceeding, ensure that your development environment meets the following requirements:

- VideoSDK Developer Account (Not having one?, follow **[VideoSDK Dashboard](https://www.videosdk.live/signup?utm_source=organicseo&utm_medium=devto&utm_campaign=screen_share_react_js)**)
- Basic understanding of React.
- **[React VideoSDK](https://www.npmjs.com/package/@videosdk.live/react-sdk)**
- Make sure Node and NPM are installed on your device.
- Basic understanding of Hooks (useState, useRef, useEffect)
- React Context API (optional)

Follow the steps to create the environment necessary to add video calls to your app. You can also find the code sample for [Quickstart here](https://github.com/videosdk-live/quickstart/tree/main/react-rtc).[​](https://docs.videosdk.live/react/guide/video-and-audio-calling-api-sdk/quick-start#create-new-react-app)

**Create a new React App using the below command.**

```
$ npx create-react-app videosdk-rtc-react-app
```

## 🛠️ Install VideoSDK[​](https://docs.videosdk.live/react/guide/video-and-audio-calling-api-sdk/quick-start#install-videosdk)

It is necessary to set up VideoSDK within your project before going into the details of integrating the Screen Share feature. Installing VideoSDK using NPM or Yarn will depend on the needs of your project.

- For NPM

```
$ npm install "@videosdk.live/react-sdk"

//For the Participants Video
$ npm install "react-player"
```

- For Yarn

```
$ yarn add "@videosdk.live/react-sdk"

//For the Participants Video
$ yarn add "react-player"
```

You are going to use functional components to leverage React's reusable component architecture. There will be components for users, videos and controls (mic, camera, leave) over the video.

<!--kg-card-begin: markdown-->
### App Architecture
<!--kg-card-end: markdown-->

The App will contain a `MeetingView` component which includes a `ParticipantView` component which will render the participant's name, video, audio, etc. It will also have a `Controls` component that will allow the user to perform operations like leave and toggle media.

![How to Integrate Screen Share Feature in React JS Video Call App?](https://docs.videosdk.live/assets/images/react-quick-start-fafbfbc2ed2d7cbfd4c5ee2e36296f9e.png)

You will be working on the following files:

- API.js: Responsible for handling API calls such as generating unique meetingId and token
- App.js: Responsible for rendering `MeetingView` and joining the meeting.

## Essential Steps to Implement Video

To add video capability to your React application, you must first complete a sequence of prerequisites.

### Step 1: Get started with API.js[​](https://docs.videosdk.live/react/guide/video-and-audio-calling-api-sdk/quick-start#step-1-get-started-with-apijs)

Before moving on, you must create an API request to generate a unique meetingId. You will need an authentication token, which you can create either through the [videosdk-rtc-api-server-examples](https://github.com/videosdk-live/videosdk-rtc-api-server-examples) or directly from the [VideoSDK Dashboard](https://app.videosdk.live/api-keys) for developers.

```
//This is the Auth token, you will use it to generate a meeting and connect to it
export const authToken = "<Generated-from-dashbaord>";
// API call to create a 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;
};
```

### Step 2: Wireframe App.js with all the components[​](https://docs.videosdk.live/react/guide/video-and-audio-calling-api-sdk/quick-start#step-2-wireframe-appjs-with-all-the-components)

To build up a wireframe of App.js, you need to use VideoSDK Hooks and Context Providers. VideoSDK provides MeetingProvider, MeetingConsumer, useMeeting, and useParticipant hooks.

First, you need to understand the **Context Provider** and Consumer. Context is primarily used when some data needs to be accessible by many components at different nesting levels.

- **MeetingProvider** : This is the Context Provider. It accepts value `config` and `token` as props. The Provider component accepts a value prop to be passed to consuming components that are descendants of this Provider. One Provider can be connected to many consumers. Providers can be nested to override values deeper within the tree.
- **MeetingConsumer** : This is the Context Consumer. All consumers that are descendants of a Provider will re-render whenever the Provider’s value prop changes.
- **useMeeting** : This is the meeting hook API. It includes all the information related to meetings such as join/leave, enable/disable the mic or webcam, etc.
- **useParticipant** : This is the participant hook API. It is responsible for handling all the events and props related to one particular participant such as **name** , **webcamStream** , **micStream** , etc.

The Meeting Context provides a way to listen for any changes that occur when a participant joins the meeting or makes modifications to their microphone, camera, and other settings.

Begin by making a few changes to the code in the **App.js** file.

```
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 ReactPlayer from "react-player";

function JoinScreen({ getMeetingAndToken }) {
  return null;
}

function ParticipantView(props) {
  return null;
}

function Controls(props) {
  return null;
}

function MeetingView(props) {
  return null;
}

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

  //Getting the meeting id by calling the api we just wrote
  const getMeetingAndToken = async (id) => {
    const meetingId =
      id == null ? await createMeeting({ token: authToken }) : id;
    setMeetingId(meetingId);
  };

  //This will set Meeting Id to null when meeting is left or ended
  const onMeetingLeave = () => {
    setMeetingId(null);
  };

  return authToken && meetingId ? (
    <MeetingProvider
      config={{
        meetingId,
        micEnabled: true,
        webcamEnabled: true,
        name: "C.V. Raman",
      }}
      token={authToken}
    >
      <MeetingView meetingId={meetingId} onMeetingLeave={onMeetingLeave} />
    </MeetingProvider>
  ) : (
    <JoinScreen getMeetingAndToken={getMeetingAndToken} />
  );
}

export default App;
```

### Step 3: Implement Join Screen[​](https://docs.videosdk.live/react/guide/video-and-audio-calling-api-sdk/quick-start#step-3-implement-join-screen)

The join screen will serve as a medium to either schedule a new meeting or join an existing one.

```
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>
  );
}
```
<!--kg-card-begin: markdown-->
#### Output
<!--kg-card-end: markdown-->

![How to Integrate Screen Share Feature in React JS Video Call App?](https://docs.videosdk.live/assets/images/react-join-screen-06fb57cf0d9e3bcc1e7da9fc032298c3.jpeg)

### Step 4: Implement MeetingView and Controls[​](https://docs.videosdk.live/react/guide/video-and-audio-calling-api-sdk/quick-start#step-4-implement-meetingview-and-controls)

The next step is to create `MeetingView` and `Controls` components to manage features such as join, leave, mute, and unmute.

```
function MeetingView(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 } = useMeeting({
    //callback for when meeting is joined successfully
    onMeetingJoined: () => {
      setJoined("JOINED");
    },
    //callback for when meeting is left
    onMeetingLeft: () => {
      props.onMeetingLeave();
    },
  });
  const joinMeeting = () => {
    setJoined("JOINING");
    join();
  };

  return (
    <div className="container">
      <h3>Meeting Id: {props.meetingId}</h3>
      {joined && joined == "JOINED" ? (
        <div>
          <Controls />
          //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>
  );
}

function Controls() {
  const { leave, toggleMic, toggleWebcam } = useMeeting();
  return (
    <div>
      <button onClick={() => leave()}>Leave</button>
      <button onClick={() => toggleMic()}>toggleMic</button>
      <button onClick={() => toggleWebcam()}>toggleWebcam</button>
    </div>
  );
}
```

_Control Component_
<!--kg-card-begin: markdown-->
#### Output of Controls Component
<!--kg-card-end: markdown-->

![How to Integrate Screen Share Feature in React JS Video Call App?](https://docs.videosdk.live/assets/images/react-container-controls-2cebdfdfd1371b010b773cb6fb9c7ae8.jpeg)

### Step 5: Implement Participant View[​](https://docs.videosdk.live/react/guide/video-and-audio-calling-api-sdk/quick-start#step-5-implement-participant-view)

Before implementing the participant view, you need to understand a couple of concepts.

<!--kg-card-begin: markdown-->
#### 5.1 Forwarding Ref for mic and camera
<!--kg-card-end: markdown-->

The `useRef` hook is responsible for referencing the audio and video components. It will be used to play and stop the audio and video of the participant.

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

_Forwarding Ref for mic and camera_
<!--kg-card-begin: markdown-->
#### 5.2 useParticipant Hook
<!--kg-card-end: markdown-->

The `useParticipant` hook is responsible for handling all the properties and events of one particular participant who joined the meeting. It will take participantId as an argument.

```
const { webcamStream, micStream, webcamOn, micOn } = useParticipant(
  props.participantId
);
```
<!--kg-card-begin: markdown-->
#### 5.3 MediaStream API
<!--kg-card-end: markdown-->

The MediaStream API is beneficial for adding a MediaTrack to the audio/video tag, enabling the playback of audio or video.

```
const webcamRef = useRef(null);
const mediaStream = new MediaStream();
mediaStream.addTrack(webcamStream.track);

webcamRef.current.srcObject = mediaStream;
webcamRef.current
  .play()
  .catch((error) => console.error("videoElem.current.play() failed", error));
```
<!--kg-card-begin: markdown-->
#### 5.4 Implement `ParticipantView`​
<!--kg-card-end: markdown-->

Now you can use both of the hooks and the API to create `ParticipantView`

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

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

  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");
          }}
        />
      )}
    </div>
  );
}
```

## 🔄 Integrate Screen Share Feature

Screen sharing in a meeting is the process of sharing your computer screen with other participants in the meeting. It allows everyone in the meeting to see exactly what you are seeing on your screen, which can be helpful for presentations, demonstrations, or collaborations.

### Enable Screen Share

- By using the `enableScreenShare()` function of the `useMeeting` hook, the local participant can share their desktop screen with other participants.
- The Screen Share stream of a participant can be accessed from the `screenShareStream` property of the `useParticipant` hook.

### Disable Screen Share

- By using the `disableScreenShare()` function of the `useMeeting` hook, the local participant can stop sharing their desktop screen with other participants.

### Toggle Screen Share[​](https://docs.videosdk.live/react/guide/video-and-audio-calling-api-sdk/handling-media/screen-share#togglescreenshare)

- By using the `toggleScreenShare()` function of the `useMeeting` hook, the local participant can start or stop sharing their desktop screen with other participants based on the current state of the screen sharing.
- The Screen Share stream of a participant can be accessed from the `screenShareStream` property of `useParticipant` hook.

> **Note** : Screen Sharing is only supported in the **Desktop browsers** and **not in mobile/tab browser**.

```
const ControlsContainer = () => {
  //Getting the screen-share method from hook
  const { toggleScreenShare } = useMeeting();

  return (
    //...
    //...
    <button onClick={() => toggleScreenShare()}>Screen Share</button>
    //...
    //...
  );
};
```

### Events associated with toggleScreenShare[​](https://docs.videosdk.live/react-native/guide/video-and-audio-calling-api-sdk/handling-media/screen-share#events-associated-with-togglescreenshare)

- Every Participant will receive a callback on  [`onStreamEnable()`](https://docs.videosdk.live/react/api/sdk-reference/use-participant/events#onstreamdisabled) event of the [`useParticipant()`](https://docs.videosdk.live/react/api/sdk-reference/use-participant/introduction) hook with the `Stream` object, if the **screen share broadcasting was started**.
- Every Participant will receive a callback on [`onStreamDisabled()`](https://docs.videosdk.live/react/api/sdk-reference/use-participant/events#onstreamdisabled) event of the [`useParticipant()`](https://docs.videosdk.live/react/api/sdk-reference/use-participant/introduction) hook with the `Stream` object, if the **screen share broadcasting was stopped**.
- Every Participant will receive the [`onPresenterChanged()`](https://docs.videosdk.live/react/api/sdk-reference/use-meeting/events#onpresenterchanged) callback of the [`useMeeting`](https://docs.videosdk.live/react/api/sdk-reference/use-meeting/introduction) hook, providing the `participantId` as the `presenterId` of the participant who started the screen share or `null` if the screen share was turned off.

```
import { useParticipant, useMeeting } from "@videosdk.live/react-sdk";

const MeetingView = () => {
  //Callback for when the presenter changes
  function onPresenterChanged(presenterId) {
    if(presenterId){
      console.log(presenterId, "started screen share");
    }else{
      console.log("someone stopped screen share");
    }
  }

  const { participants } = useMeeting({
    onPresenterChanged,
    ...
  });

  return <>...</>
}

const ParticipantView = (participantId) => {
  //Callback for when the participant starts a stream
  function onStreamEnabled(stream) {
    if(stream.kind === 'share'){
      console.log("Share Stream On: onStreamEnabled", stream);
    }
  }

  //Callback for when the participant stops a stream
  function onStreamDisabled(stream) {
    if(stream.kind === 'share'){
      console.log("Share Stream Off: onStreamDisabled", stream);
    }
  }

  const {
    displayName
    ...
  } = useParticipant(participantId,{
    onStreamEnabled,
    onStreamDisabled
    ...
  });
  return <> Participant View </>;
}
```

### Screen Share with Audio[​](https://docs.videosdk.live/react/guide/video-and-audio-calling-api-sdk/handling-media/screen-share#screen-share-with-audio)

To enable screen sharing with audio, select the **Share tab audio** option when sharing the Chrome tab as shown below.

![How to Integrate Screen Share Feature in React JS Video Call App?](https://docs.videosdk.live/assets/images/screenshare-with-audio-ca8ee299f68c32ba08cd811e3fb7cd2f.png)

After clicking the `Share` button, you will receive the selected tab's audio stream in the participant's `screenShareAudioStream`.

> 📝 **NOTE** : Screen Share with Audio is only supported while sharing **Chrome Tab** in a **Chromium based browser** like Google Chrome, Brave etc.

### Rendering Screen Share and Screen Share Audio​

- To render the screen share, you will need the `participantId` of the user presenting the screen. This can be obtained from the `presenterId` property of the `useMeeting` hook. 

```
const MeetingView = () => {
  //
  const { presenterId } = useMeeting();

  return <>{presenterId && <PresenterView presenterId={presenterId} />}</>;
};

const PresenterView = ({ presenterId }) => {
  return <div>PresenterView</div>;
};
```

- Now that you have the `presenterId`, you can obtain the `screenShareStream` using the `useParticipant` hook and play it in the video tag.

```
const PresenterView = ({ presenterId }) => {
  const { screenShareStream, screenShareOn } = useParticipant(presenterId);

  //Creating a media stream from the screen share stream
  const mediaStream = useMemo(() => {
    if (screenShareOn && screenShareStream) {
      const mediaStream = new MediaStream();
      mediaStream.addTrack(screenShareStream.track);
      return mediaStream;
    }
  }, [screenShareStream, screenShareOn]);

  return (
    <>
      // playing the media stream in the ReactPlayer
      <ReactPlayer
        //
        playsinline // extremely crucial prop
        playIcon={<></>}
        //
        pip={false}
        light={false}
        controls={false}
        muted={true}
        playing={true}
        //
        url={mediaStream} // passing mediastream here
        //
        height={"100%"}
        width={"100%"}
        onError={(err) => {
          console.log(err, "presenter video error");
        }}
      />
    </>
  );
};
```

- You can then add the screen share audio to this component by retrieving the `screenShareAudioStream` from the `useParticipant` hook.

```
const PresenterView = ({ presenterId }) => {
  const { screenShareAudioStream, isLocal, screenShareStream, screenShareOn } =
    useParticipant(presenterId);

  // Creating a reference to the audio element
  const audioPlayer = useRef();

  // Playing the screen share audio stream
  useEffect(() => {
    if (
      !isLocal &&
      audioPlayer.current &&
      screenShareOn &&
      screenShareAudioStream
    ) {
      const mediaStream = new MediaStream();
      mediaStream.addTrack(screenShareAudioStream.track);

      audioPlayer.current.srcObject = mediaStream;
      audioPlayer.current.play().catch((err) => {
        if (
          err.message ===
          "play() failed because the user didn't interact with the document first. https://goo.gl/xX8pDD"
        ) {
          console.error("audio" + err.message);
        }
      });
    } else {
      audioPlayer.current.srcObject = null;
    }
  }, [screenShareAudioStream, screenShareOn, isLocal]);

  return (
    <>
      {/*... React player is here */}
      //Adding this audio tag to play the screen share audio
      <audio autoPlay playsInline controls={false} ref={audioPlayer} />
    </>
  );
};
```

> ⚠️ **CAUTION** : To use the audio and video communications in the web browser, your site must be SSL enabled i.e. it must be secured and running on https.

## Conclusion

Congratulation! You've successfully integrated screen sharing into your React video call app using videoSDK. Incorporating a screen share feature into your React JS video call app elevates its functionality, enabling seamless collaboration and communication among users. By integrating this feature, you empower users to share their screens effortlessly, facilitating real-time demonstrations, presentations, and troubleshooting sessions. With careful implementation and consideration of performance and security aspects, your app becomes a powerful tool for remote teams, educators, and businesses to enhance productivity and engagement

Ready to empower your video call app with advanced features? Explore [VideoSDK](https://www.videosdk.live/), the comprehensive solution for building scalable and customizable video applications. **[Sign up with VideoSDK](https://www.videosdk.live/signup?utm_source=organicseo&utm_medium=devto&utm_campaign=screen_share_react_js)** and get **10000 minutes free** to take the video app to the next level!