Overview
LiveKit supports screen sharing natively across all platforms. Your screen is published as a video track, just like your camera. Some platforms support local audio sharing as well.
The steps are somewhat different for each platform:
// The browser will prompt the user for access and offer a choice of screen, window, or tabawait room.localParticipant.setScreenShareEnabled(true);
On iOS, LiveKit integrates with ReplayKit in two modes:
- In-app capture (default): For sharing content within your app
- Broadcast capture: For sharing screen content even when users switch to other apps
In-app capture
The default in-app capture mode requires no additional configuration, but shares only the current application.
localParticipant.setScreenShare(enabled: true)
Broadcast capture
To share the full screen while your app is running in the background, you'll need to set up a Broadcast Extension. This will allow the user to "Start Broadcast". You can prompt this from your app or the user can start it from the control center.
The full steps are described in our iOS screen sharing guide, but a summary is included below:
- Add a new "Broadcast Upload Extension" target with the bundle identifier
<your-app-bundle-identifier>.broadcast
. - Replace the default
SampleHandler.swift
with the following:
import LiveKit#if os(iOS)@available(macCatalyst 13.1, *)class SampleHandler: LKSampleHandler {override var enableLogging: Bool { true }}#endif
- Add both your main app and broadcast extension to a common App Group, named
group.<your-app-bundle-identifier>
. - Present the broadcast dialog from your app:
localParticipant.setScreenShare(enabled: true)
On Android, screen capture is performed using MediaProjectionManager
:
// Create an intent launcher for screen capture// This *must* be registered prior to onCreate(), ideally as an instance valval screenCaptureIntentLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->val resultCode = result.resultCodeval data = result.dataif (resultCode != Activity.RESULT_OK || data == null) {return@registerForActivityResult}lifecycleScope.launch {room.localParticipant.setScreenShareEnabled(true, data)}}// When it's time to enable the screen share, perform the followingval mediaProjectionManager =getSystemService(MEDIA_PROJECTION_SERVICE) as MediaProjectionManagerscreenCaptureIntentLauncher.launch(mediaProjectionManager.createScreenCaptureIntent())
room.localParticipant.setScreenShareEnabled(true);
On Android, you would have to define a foreground service in your AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"><application>...<serviceandroid:name="de.julianassmann.flutter_background.IsolateHolderService"android:enabled="true"android:exported="false"android:foregroundServiceType="mediaProjection" /></application></manifest>
On iOS, follow this guide to set up a Broadcast Extension.
yield return currentRoom.LocalParticipant.SetScreenShareEnabled(true);
Sharing browser audio
Audio sharing is only possible in certain browsers. Check browser support on the MDN compatibility table.
To share audio from a browser tab, you can use the createScreenTracks
method with the audio option enabled:
const tracks = await localParticipant.createScreenTracks({audio: true,});tracks.forEach((track) => {localParticipant.publishTrack(track);});
Testing audio sharing
Publisher
When sharing audio, make sure you select a Browser Tab (not a Window) and ☑️ Share tab audio, otherwise no audio track will be generated when calling createScreenTracks
:

Subscriber
On the receiving side, you can use RoomAudioRenderer
to play all audio tracks of the room automatically, AudioTrack
or your own custom <audio>
tag to add the track to the page. If you don't hear any sound, check you're receiving the track from the server:
room.getParticipantByIdentity('<participant_id>').getTrackPublication('screen_share_audio');