Screen Share - React Native
This feature enables hosts to start or stop sharing their screen with other hosts and audience members during the live stream. Only hosts (in SEND_AND_RECV mode) can broadcast their screen, while audience members (in RECV_ONLY mode) can view it in real time.
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.
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.
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 the host's microphone track. It will only be shared if the microphone is enabled. If the microphone is muted, the system audio will also be muted.
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:
- React Native iOS Screen Share
- For an Expo app: React Native Expo iOS Screen Share
enableScreenShare() shows the system broadcast picker itself. You do not need VideosdkRPK or any other code of your own to show it.
Screen Share Controls
enableScreenShare()
-
By using the
enableScreenShare()function of theuseRoomhook, the host can share their device screen to other hosts and audience members. -
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. Learn more in Custom Screen Share Track. -
A stopped or released track is refused with
ERROR_INVALID_CUSTOM_VIDEO_TRACK(3029). -
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 host 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 the host is already sharing rejects with
3054ERROR_ALREADY_IN_REQUESTED_STATE. -
The Screen Share stream of a participant can be accessed from the
screenShareStreamproperty of theuseParticipanthook.
disableScreenShare()
- By using the
disableScreenShare()function of theuseRoomhook, the host can stop sharing their screen to other hosts and audience members.
toggleScreenShare()
-
By using the
toggleScreenShare()function of theuseRoomhook, the host can start or stop sharing their screen to other hosts and audience members based on the current state of the screen sharing. -
It takes the same optional track as
enableScreenShare(), and uses it only when screen sharing is turned on. -
The Screen Share stream of a participant can be accessed from the
screenShareStreamproperty ofuseParticipanthook.
Audience members (in RECV_ONLY mode) cannot share their screen. For them, enableScreenShare() and toggleScreenShare() reject with 3066 ERROR_ACTION_NOT_SUPPORTED_IN_MODE. Show the screen share controls only to hosts, because on Android createScreenShareVideoTrack() shows the consent dialog before that rejection.
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({
encoderConfig: "h720p_15fps",
withAudio: false, // Android only
});
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 {
// 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);
}
};
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;
Handling Screen Share Events
Events associated with enableScreenShare
-
Every Participant—including all the hosts and audience members will receive a callback on
onStreamEnabled()event of theuseParticipant()hook with theRTCStreamobject. -
Every participant—including all the hosts and audience members will receive the
onPresenterChanged()callback of theuseRoomhook, which provides theparticipantIdas thepresenterIdof the participant who started the screen share.
Events associated with disableScreenShare
-
Every Participant—including all the hosts and audience members will receive a callback on
onStreamDisabled()event of theuseParticipant()hook with theRTCStreamobject. -
Every Participant—including all the hosts and audience members will receive the
onPresenterChanged()callback of theuseRoomhook, with thepresenterIdasnull, indicating that there is no current presenter.
Events associated with toggleScreenShare
-
Every Participant—including all the hosts and audience members will receive a callback on
onStreamEnabled()event of theuseParticipant()hook with theRTCStreamobject, if the screen share broadcasting was started. -
Every Participant—including all the hosts and audience members will receive a callback on
onStreamDisabled()event of theuseParticipant()hook with theRTCStreamobject, if the screen share broadcasting was stopped. -
Every Participant—including all the hosts and audience members will receive the
onPresenterChanged()callback of theuseRoomhook, providing theparticipantIdas thepresenterIdof the participant who started the screen share ornullif the screen share was turned off.
import { useParticipant, useRoom } from "@videosdk.live/react-native-sdk";
import { Text } from "react-native";
const LiveStreamView = () => {
//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 } = useRoom({
onPresenterChanged,
// ...
});
return <>{/* Your live stream UI */}</>;
}
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 <Text>{displayName}</Text>;
}
Rendering the Screen Share Stream
To display the screen share from another host:
1. Get the presenter's id
To render the screenshare, you will need the participantId of the host presenting the screen. Call getActivePresenterId() of the useRoom hook. 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
Now that you have the presenter's id, you can obtain the screenShareStream using the useParticipant hook and play it.
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;
API References
Got a Question? Ask us on discord

