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.
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
- Android Setup
- iOS Setup
- Expo Setup
- System Audio with Screen Share
- Screen Share Controls
- Rendering the Screen Share Stream
- Handling Screen Share Events
- 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.
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 thecreateScreenShareVideoTrack()method,withAudiois a flag that controls whether system audio is shared. Set it totrueto include system audio with the screen share, orfalse(the default) to share only the screen without audio. Then pass the track toenableScreenShare(). 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 withwithAudioset tofalse. -
System audio capture needs the
android.permission.RECORD_AUDIOpermission, 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.
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 toenableScreenShare(). ItsencoderConfigsets the resolution and frame rate:h360p_30fps,h480p_15fps,h480p_30fps,h720p_5fps,h720p_15fps(the default),h720p_30fps,h1080p_15fpsorh1080p_30fps. -
On Android,
createScreenShareVideoTrack()shows the screen capture consent dialog. If the user declines, it rejects with3016ERROR_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, callenableScreenShare()again to show it again. -
Sharing has started when the
sharestream of the local participant firesonStreamEnabled, not when thePromiseresolves. -
If the user stops sharing from the system controls, such as iOS Control Center, the SDK ends the share for you and
onStreamDisabledfires. -
Calling it while you are already sharing rejects with
3054ERROR_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);
}
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

