Skip to main content

Receive presentation

An important feature in any video conference application is screen sharing or "presentation". This feature allows the users to collaborate in a more flexible way. They can share any type of document or tools, such a whiteboard, powerpoint or even videos.

We have divided the lessons about presentation into two parts. We will start by receiving a presentation, and in the next lesson, we will learn how to send a presentation.

During this tutorial we will perform the following tasks:

  • Set handlers related for receiving a presentation.
  • Define a function to choose which video display in the main region (remote participants or presentation).
  • Define the useEffect hook to configure the initial state of the component after re-rendering.
  • Create the HTML Video element for the presentation.
  • Set the onClick listener for changing between the video with the remote participants and the presentation.

After all these changes, we will be able to receive a presentation and in the next lesson we will learn how to send it.

You can download the starter code from Step.04-Exercise-Receive-presentation.

App component

We will start the journey by editing the file src/App.js. We will attach functions for three events:

pexRTC.onPresentation = handlePresentation;
pexRTC.onPresentationConnected = handlePresentationConnected;
pexRTC.onPresentationDisconnected = handlePresentationDisconnected;

First we define the handler for when a new incoming presentation is received:

const handlePresentation = (setting, presenter, uuid, presenter_source) => {
if (setting) pexRTC.getPresentation();
};

This event receives information about the presentation, but not the presentation itself. For that we have to trigger pexRTC.getPresentation() manually.

After launching getPresentation the event onPresentationConnected will be triggered and will contain the MediaStream with the presentation.

In the handler we save this stream in the app state:

const handlePresentationConnected = stream => {
setPresentationStream(stream);
};

The last handler is triggered when the user stops sharing their screen. In this case we will set the MediaStream to null to indicate the rest of the application that the presentation ended:

const handlePresentationDisconnected = reason => {
if (!pexRTC.screenshare_requested) {
setPresentationStream(null);
}
};

Before removing the presentation, we must check that the current user of the application didn't enable screen sharing themself.

Conference component

Now we will edit the file src/components/Conference/Conference.js and in this file we will define a new HTML Video tag. This new tag will be used to display a secondary media stream. We also will exchange the video located in the main region if the user click on this video.

Next we will define a state variable that will indicate which video stream will be displayed in the main region of the page. It could be the video with the remote participants or the presentation. The video that is not in the main region will be positioned in the top-left corner and it will be much smaller:

const [presentationInMain, setPresentationInMain] = useState();

Next we will define the function that will be triggered every time the user clicks over the video that is not in the main region:

const switchVideos = event => {
if (event.target.className === 'presentation-video') {
setPresentationInMain(true);
} else {
setPresentationInMain(false);
}
};

Next we use the useCallback hook over the switchVideos function, since this will help to avoid video flickering when the component is re-rendered:

const memoizedSwitchVideos = React.useCallback(switchVideos, []);

The next step is to use the useEffect hook to define what should happen when the component is re-rendered due to a change in the dependencies:

useEffect(() => {
if (!props.presentationStream) {
if (presentationInMain != null) setPresentationInMain(null);
} else {
if (presentationInMain == null && !props.pexRTC.screenshare_requested) {
setPresentationInMain(true);
}
}
}, [
presentationInMain,
props.localStream,
props.pexRTC.screenshare_requested,
props.presentationStream,
]);

With this code we will have to cope with two different situations:

  • If the presentation isn't active and the value of presentationInMain changed, we reset its value to the original value (null).

  • If the presentation is active, presentationInMain is uninitialized and screenshare_requested is false, that means that we are receiving a presentation and not sending it, we set presentationInMain to true.

With this modification, we will display by default the remote presentation in the main video region, and in case the user is the one that is sending the presentation (next lesson), they will see it in a small thumbnail.

Next we will modify the remote-video element and add the onClick attribute to call the memoized function that we have defined before:

<Video
className="remote-video"
mediaStream={props.remoteStream}
onClick={memoizedSwitchVideos}
/>

The last thing that we need is to define a new video that will contain the presentation that we will receive. In the similar way that before, we assign a function to the onClick event that will switch the video that is displayed in the main region:

{
props.presentationStream && (
<Video
className="presentation-video"
mediaStream={props.presentationStream}
onClick={memoizedSwitchVideos}
/>
);
}

With this last modification we have everything in place that we will need for receiving a presentation. In the next tutorial we will see how to share our screen with other participants.

Run the app

To test your new feature, you will need an application that already has the capability to send a presentation. Our recommendation is to test it with the Pexip Web App 3. This way, a participant will join to the conference using your app and a second participant will use the Web App 3.

You can compare your code with the solution in Step.04-Solution-Receive-presentation. You can also check the differences with the previous lesson in the git diff.

Receive Presentation