Tech

Screen sharing

  • Low Latency
  • WebRTC
  • Screen
  • Window
  • Tab
  • SFU

Stream a screen, window or browser tab to other participants with low latency. Mobile devices can share too: the Android and iOS SDKs capture the device screen right from your app. Viewers watch it on any device, just like a desktop share.

  • Web
  • iOS
  • Android

Overview

Screen Sharing isn't all that different from regular Live Streaming. The main difference is the video source: instead of capturing video from a camera, you capture an application window or an entire screen.

The resulting video stream can be delivered to viewers just like any other live stream. However, screen sharing comes with a few challenges of its own.

Resolution

Screen sharing often involves higher resolutions than camera streaming. Ideally, the captured video should preserve the native resolution of the selected screen or application window without unnecessary scaling.

A developer with arms spread wide, showing the full size of the picture.

For example, if an application window is 600 × 850 pixels, those dimensions should be preserved in the stream, allowing viewers to see the content in its original resolution. This is particularly important for text, interfaces, diagrams, and other fine details.

Screen1920 × 1080
Window600 × 850
Tab1280 × 960

Dynamic resizing

Application windows don't always stay the same size. Users can resize them at any moment by dragging their edges. Screen sharing needs to adapt to these changes in real time, updating the captured video dimensions without interrupting the stream. Viewers should see the changes as quickly and smoothly as possible.

A developer stretching a resistance band diagonally.

Security

Screen sharing requires special permissions from the browser and operating system. Unlike camera access, which a browser may remember, screen capture generally requires users to select what they want to share each time.

A developer in sunglasses and a black suit, standing guard like a security officer.

The browser presents a selection dialog where users choose a screen, application window, or browser tab, preventing websites from silently capturing desktop content without their consent.

Additional streams

A silent screen share on its own isn't particularly engaging. After all, someone needs to explain what's happening on the screen! That's why screen sharing is usually accompanied by additional media streams from a microphone, a camera, or both.

A developer in a headset waving while talking.

This allows presenters to demonstrate an application while explaining their actions, answering questions, and interacting with their audience in real time.

How it works

Screen sharing works in much the same way across different devices and platforms. The application uses the appropriate SDK to establish a streaming session with the Media Server. It then captures the screen or application window and sends the captured video to the server.

A developer surrounded by coding icons: a play button, gears, a terminal, a bug and a check mark.

The SDK handles session negotiation and media transmission, while the application manages screen capture using the platform's native capabilities.

On the viewer's side, there's nothing particularly special about screen sharing. The captured content is received and played back just like any other live stream.

Now let's see how to implement screen sharing with each of the four SDKs.

The code looks a little different on each platform, but the idea is the same: capture the screen, establish a streaming session, and publish the video to the Media Server.

Web SDK

Screen sharing from a browser is handled by the Web SDK. All you need is a small piece of code:

session
  .createStream({
    name: 'alice-screen',
    display: localPreview,
    constraints: {
      video: {
        type: 'screen',
        mediaSource: 'screen',
        width: 1920,
        height: 1080,
        frameRate: 10,
      },
      audio: false,
    },
  })
  .publish();

The stream name is set by name: 'alice-screen': viewers play the screen by this name.

Explore Screen Sharing example↗

Android SDK

On Android the user approves capture in a system dialog, and the app keeps a foreground service running while sharing. Publishing the screen takes a few lines:

StreamOptions options = new StreamOptions("alice-screen");
VideoConstraints video = new VideoConstraints();
video.setResolution(1920, 1080);
video.setVideoFps(10);
options.getConstraints().setVideoConstraints(video);
options.getConstraints().updateAudio(false);

Stream stream = session.createStream(options);

// mediaProjectionData: from the capture dialog
WebRTCMediaProvider.getInstance().setVideoCapturer(
    new ScreenCapturerAndroid(null, mediaProjectionData,
        new MediaProjection.Callback() {}));

stream.publish();

The stream name is set by new StreamOptions("alice-screen"): viewers play the screen by this name.

Explore Screen Sharing example↗

iOS SDK

On iOS the screen is captured by a ReplayKit broadcast extension. The system hands it screen frames, and the SDK publishes them through a video capturer:

// ReplayKit delivers screen frames to the capturer
override func processSampleBuffer(
    _ buffer: CMSampleBuffer, with type: RPSampleBufferType
) {
    capturer.processSampleBuffer(buffer, with: type)
}

let options = FPWCSApi2StreamOptions()
options.name = "alice-screen"
options.constraints = FPWCSApi2MediaConstraints(
    audio: false, videoCapturer: capturer)

let stream = try session.createStream(options)
try stream.publish()

The stream name is set by options.name = "alice-screen": viewers play the screen by this name.

Explore Screen Capturer example↗

SFU SDK

In a video room the screen is one more track of the participant's connection, published next to the camera and microphone. The SFU SDK marks it as screen content, so other participants can lay it out differently:

const stream = await navigator.mediaDevices.getDisplayMedia({
  video: { width: 1920, height: 1080 },
});

const config = {};
stream.getTracks().forEach((track) => {
  config[track.id] = 'screen';
  pc.addTransceiver(track, {
    direction: 'sendonly',
    streams: [stream],
  });
});

await room.updateState(config);

The track is identified by its id in config[track.id] = 'screen': the room marks the track with this id as screen content.

Explore SFU client example↗

Screen sharing live demo

No setup, no installation. Press Share Screen, choose a screen, window or tab in the browser dialog, and watch it come back from the Media Server as a live stream.

Try Live Demo↗

Launch your screen sharing server

LLcast will deploy a dedicated Media Server just for you, ready to receive your screen-sharing streams. Share your screen and experiment with different settings.