Skip to main content
Version: 2.x.x

Screen Share - React Native

Screen sharing during a room allows you to broadcast your device's screen to all participants. This guide will help you set up screen sharing in your React Native application using VideoSDK, covering both Android and iOS platforms.

note

This page uses the following asynchronous methods. Refer to their API reference for the errors each Promise may reject with, and handle these rejections appropriately based on your use case.

Contents​

  1. Android Setup
  2. iOS Setup
  3. Expo Setup
  4. System Audio with Screen Share
  5. Screen Share Controls
  6. Rendering the Screen Share Stream
  7. Handling Screen Share Events
  8. API References

Android Setup​

Screen sharing on Android needs no extra setup in your app. The SDK adds the FOREGROUND_SERVICE and FOREGROUND_SERVICE_MEDIA_PROJECTION permissions and its own screen share foreground service to your app's manifest, and it shows its own notification while you share.

caution

If your app used v1.x.x of the SDK, remove the live.videosdk.rnwebrtc.MediaProjectionService and live.videosdk.rnwebrtc.MediaProjectionServiceTask services and the live.videosdk.rnwebrtc meta-data entries from your AndroidManifest.xml. Those classes no longer exist. Learn more in the Migration Guide.


iOS Setup​

On iOS, your app needs a Broadcast Upload Extension, and your app's Info.plist needs the RTCScreenSharingExtension and RTCAppGroupIdentifier keys. To set them up, follow the dedicated guide:

enableScreenShare() shows the system broadcast picker itself. You do not need VideosdkRPK or any other code of your own to show it.


Expo Setup​

To enable screen sharing in your React Native Expo app for iOS, follow the dedicated integration guide below:

The plugin from that guide creates the Broadcast Upload Extension and the Info.plist keys. Call enableScreenShare() to show the broadcast picker; you do not need the plugin's VideosdkRPK module.


System Audio with Screen Share (Android Only)​

  • You can share the device's audio along with the screen.

  • withAudio: In the createScreenShareVideoTrack() method, withAudio is a flag that controls whether system audio is shared. Set it to true to include system audio with the screen share, or false (the default) to share only the screen without audio. Then pass the track to enableScreenShare(). On iOS, the flag has no effect.

  • If you call enableScreenShare() without a track, Android shares the system audio too. To share only the screen, pass a track created with withAudio set to false.

  • System audio capture needs the android.permission.RECORD_AUDIO permission, which your app also needs for the microphone.

  • Devices running Android 9 (API Level 28) or below will not support the System Audio sharing feature.

  • Apps that do not allow their audio to be captured are not heard in the share.

note

The system audio is mixed into your microphone track. It will only be shared if the microphone is enabled. If the microphone is muted, the system audio will also be muted.


Screen Share Controls​

Use the useRoom hook to control screen sharing within your application.

enableScreenShare()​

Starts sharing your device's screen with other participants.

  • Create the screen share track first with createScreenShareVideoTrack(), and pass it to enableScreenShare(). Its encoderConfig sets the resolution and frame rate: h360p_30fps, h480p_15fps, h480p_30fps, h720p_5fps, h720p_15fps (the default), h720p_30fps, h1080p_15fps or h1080p_30fps.

  • On Android, createScreenShareVideoTrack() shows the screen capture consent dialog. If the user declines, it rejects with 3016 ERROR_GET_DISPLAY_MEDIA_PERMISSION_DENIED.

  • On iOS, enableScreenShare() shows the system broadcast picker, and screen capture starts when the user taps Start Broadcast. If the user closes the picker, call enableScreenShare() again to show it again.

  • Sharing has started when the share stream of the local participant fires onStreamEnabled, not when the Promise resolves.

  • If the user stops sharing from the system controls, such as iOS Control Center, the SDK ends the share for you and onStreamDisabled fires.

  • Calling it while you are already sharing rejects with 3054 ERROR_ALREADY_IN_REQUESTED_STATE.

Usage:

import {
createScreenShareVideoTrack,
useRoom,
} from "@videosdk.live/react-native-sdk";

const { enableScreenShare } = useRoom();

// Start screen sharing
try {
const screenShareTrack = await createScreenShareVideoTrack({
encoderConfig: "h720p_15fps",
withAudio: false, // Android only
});
await enableScreenShare(screenShareTrack);
} catch (err) {
console.error("enableScreenShare failed:", err);
}
  • To learn more about the screen share track, see Custom Screen Share Track.

  • A stopped or released track is refused with ERROR_INVALID_CUSTOM_VIDEO_TRACK (3029).

disableScreenShare()​

Stops sharing your screen.

Usage:

const { disableScreenShare } = useRoom();

// Stop screen sharing
try {
await disableScreenShare();
} catch (err) {
console.error("disableScreenShare failed:", err);
}

toggleScreenShare()​

Toggles screen sharing on or off based on its current state.

Usage:

import {
createScreenShareVideoTrack,
useRoom,
} from "@videosdk.live/react-native-sdk";

const { toggleScreenShare, isScreenSharing } = useRoom();

// Toggle screen sharing
try {
// Create a track only when screen sharing is about to start
const screenShareTrack = isScreenSharing
? undefined
: await createScreenShareVideoTrack({ encoderConfig: "h720p_15fps" });
await toggleScreenShare(screenShareTrack);
} catch (err) {
console.error("toggleScreenShare failed:", err);
}
note

toggleScreenShare() takes the same optional track as enableScreenShare(), and uses it only when screen sharing is turned on.

Example​

import React from "react";
import {
createScreenShareVideoTrack,
useRoom,
} from "@videosdk.live/react-native-sdk";
import { TouchableOpacity, Text } from "react-native";

const RoomControls = () => {
const {
enableScreenShare,
disableScreenShare,
toggleScreenShare,
isScreenSharing,
} = useRoom();

const handleEnableScreenShare = async () => {
try {
const screenShareTrack = await createScreenShareVideoTrack();
await enableScreenShare(screenShareTrack);
} catch (err) {
console.error("enableScreenShare failed:", err);
}
};

const handleDisableScreenShare = async () => {
try {
await disableScreenShare();
} catch (err) {
console.error("disableScreenShare failed:", err);
}
};

const handleToggleScreenShare = async () => {
try {
const screenShareTrack = isScreenSharing
? undefined
: await createScreenShareVideoTrack();
await toggleScreenShare(screenShareTrack);
} catch (err) {
console.error("toggleScreenShare failed:", err);
}
};

return (
<>
<TouchableOpacity onPress={handleEnableScreenShare}>
<Text>Enable Screen Share</Text>
</TouchableOpacity>

<TouchableOpacity onPress={handleDisableScreenShare}>
<Text>Disable Screen Share</Text>
</TouchableOpacity>

<TouchableOpacity onPress={handleToggleScreenShare}>
<Text>Toggle Screen Share</Text>
</TouchableOpacity>
</>
);
};

export default RoomControls;

Rendering the Screen Share Stream​

To display the screen share from another participant:

1. Get the presenter's id​

Call getActivePresenterId() from the useRoom hook. It returns the id of the participant currently sharing their screen, or null. Calling it while rendering re-renders the component when the presenter changes.

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

const RoomView = () => {
const { getActivePresenterId } = useRoom();
const presenterId = getActivePresenterId();

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

export default RoomView;

2. Access the Screen Share Stream​

Use the useParticipant hook with the presenter's id to access the screen share stream.

import React from "react";
import {
useParticipant,
MediaStream,
RTCView,
} from "@videosdk.live/react-native-sdk";

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

if (!screenShareOn || !screenShareStream) return null;

return (
<RTCView
streamURL={new MediaStream([screenShareStream.track]).toURL()}
objectFit="contain"
style={{ flex: 1 }}
/>
);
};

export default PresenterView;

Handling Screen Share Events​

React to changes in screen sharing status by handling events provided by the SDK.

onPresenterChanged​

Triggered when a participant starts or stops screen sharing.

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

const RoomView = () => {
const onPresenterChanged = (presenterId) => {
if (presenterId) {
console.log(`${presenterId} started screen sharing`);
} else {
console.log("Screen sharing stopped");
}
};

useRoom({ onPresenterChanged });

return <>{/* Your UI components */}</>;
};

export default RoomView;

onStreamEnabled and onStreamDisabled​

Listen for when a participant's screen share stream is enabled or disabled.

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

const ParticipantView = ({ participantId }) => {
const onStreamEnabled = (stream) => {
if (stream.kind === "share") {
console.log(`Participant ${participantId} started screen sharing`);
}
};

const onStreamDisabled = (stream) => {
if (stream.kind === "share") {
console.log(`Participant ${participantId} stopped screen sharing`);
}
};

useParticipant(participantId, {
onStreamEnabled,
onStreamDisabled,
});

return <>{/* Participant UI components */}</>;
};

export default ParticipantView;

API References​

Got a Question? Ask us on discord