Livqeno Docs

Screen Sharing

Publishing a screen share — Web and Flutter today; not yet on React Native.

await room.enableScreenShare();

Or, using the create-then-publish pattern:

const track = await client.createScreenShareTrack();
await room.publish(track);

Both use the browser's native getDisplayMedia() — there's no custom capture code, and no dependency on a particular browser's screen-picker UI.

Not available on React Native yet. @ravenkash/react-native reuses the same Room class as web and Flutter for camera/microphone, but mobile screen capture needs its own native integration per platform (ReplayKit on iOS, MediaProjection on Android) that hasn't been built. Calling enableScreenShare() there is not documented and should not be relied on.

A known rough edge: source labelling

A subscriber normally learns that a track is a screen share from the source Livqeno announces, which the publisher declares alongside the track. That declaration is matched to the track by the id in the SDP msid.

When a screen share is published onto a transceiver the SFU had already created for it, the browser can leave the SFU's own msid in the m-section — Chrome will not rewrite an id it inherited from the remote offer. The SDK offers once more to get its ids onto the wire, and warns if that does not take. When it does not, the SFU falls back to inferring the source from the codec kind, which reads a screen share as a camera: the media arrives and plays, but a layout keyed on track.kind may put the shared window in the face tile.

Publishing the screen share on its own transceiver would settle it, and is not shipped because this SFU does not answer a client offer that adds m-sections — the publish would never complete. It needs an SFU-side change. Until then, a layout that must be certain should carry its own hint (a data message, or your own participant metadata) rather than relying on source for a screen share.

What's not included (Web and Flutter)

Screen sharing currently surfaces video only. If the browser or OS also offers a screen-share-audio track (sharing a browser tab with sound, for instance), it isn't exposed by the SDK yet. If your application needs system audio alongside the shared screen, that's a gap to plan around rather than something to work around client-side.

Stopping

await room.disableScreenShare();

Same shape as camera/microphone on both platforms — see Audio & Video for the mute-vs-unpublish distinction, which applies here too.

Expected behavior

A remote participant sees a screen share exactly like any other video track — it arrives via trackSubscribed/participantChanges and attaches the same way. There's no separate "screen share" event; the track's kind is what distinguishes it ('screenShare').

Common errors

ErrorWhyFix
User cancels the browser's share pickerNo error thrown, enableScreenShare()'s promise rejects.Treat a rejection here as "user declined," not a real failure.
enableScreenShare() throws on iOS (Flutter)No Broadcast Upload Extension configured.Add one in Xcode — there's no software-only workaround.

Production notes

  • Don't assume screen share is available — check the platform before showing the button, especially on React Native.
  • A screen share ending unexpectedly (user stops sharing from the OS chrome, not your UI) still fires the normal unpublish path — listen for it rather than assuming your own button is the only way it stops.