Tutorial: Screen Sharing

Screen Sharing

Feature Description

This article describes how to implement screen sharing functionality in the TRTC Web SDK.

Prerequisites

  1. This tutorial is based on TRTC Web SDK v4.15.0+, if your SDK is lower than this version, you can refer to the old tutorial.

    In v4.15.0+, the SDK supports publishing main stream + auxiliary stream at the same time for one Client, i.e. publishing camera + screencast streams at the same time for one Client. In older versions, you need to create additional Client separately to publish screen sharing stream.

  2. Please check browser support for TRTC Web SDK screen sharing support. Also the SDK provides TRTC.isScreenShareSupported interface to determine whether the current browser supports screen sharing or not.

  3. Browsers supported list of publishing auxiliary stream: Chrome 69+, Safari 11+, Firefox 59+, Edge 79+. BTW: Publishing auxiliary stream is supported in any environment that supports screen sharing.

What is 'Main Stream' and 'Auxiliary Stream'

In the TRTC Web SDK, a Client instance can publish two streams at the same time.

  • One is called the main stream and is typically used to publish the camera and microphone, but can also publish a custom captured stream from the business side.
  • One is called the auxiliary stream and is typically used to publish screen sharing streams.

Implementation Process

  1. Create and publish screen sharing

    const clientA = TRTC.createClient({
      mode: 'rtc',
      sdkAppId: 140000000, // your sdkAppId
      userId: 'userA', // your userId
      userSig: 'userA_sig', // your userSig
    })
    await clientA.join({ roomId: 6969 });
    const shareStream = TRTC.createStream({ 
      userId: 'userA', 
      screen: true, // capture screen sharing
    })
    await shareStream.initialize();
    await clientA.publish(shareStream, { isAuxiliary: true }); // The shareStream will publish on auxiliary stream by setting the parameter 'isAuxiliary' to true.
    
  2. Subscribe and play screen sharing

    const clientB = TRTC.createClient({
      mode: 'rtc',
      sdkAppId: 140000000, // your sdkAppId
      userId: 'userB', // your userId
      userSig: 'userB_sig', // your userSig
    })
    clientB.on('stream-added', async event => {
      const remoteStream = event.stream;
      // subscribe stream
      await clientB.subscribe(remoteStream);
      // Main stream. Generally, it's microphone, camera stream.
      if (remoteStream.getType() === 'main') {
        // 1. Put a `div` element with a id `${remoteStream.getUserId()}_main` to DOM, SDK will play stream inside the target `div` element.
        // 2. Play stream.
        await remoteStream.play(`${remoteStream.getUserId()}_main`)
      } else if (remoteStream.getType() === 'auxiliary') {
        // Auxiliary stream. Generally, it's screen sharing stream.
        // 1. Put a `div` element with a id `${remoteStream.getUserId()}_screen` to DOM, SDK will play stream inside the target `div` element.
        // Of course you can customize the id of the `div` element, here is just an example
        // 2. Play stream.
        await remoteStream.play(`${remoteStream.getUserId()}_screen`)
      }
    });
    await clientB.join({ roomId: 6969 });
    
  3. Publish camera and screen sharing at same time

    const localStream = TRTC.createStream({ 
      userId: 'userA',
      audio: true, // capture microphone
      video: true // capture camera
    })
    const shareStream = TRTC.createStream({ 
      userId: 'userA', 
      screen: true, // capture screen sharing
    })
    await localStream.initialize();
    await shareStream.initialize();
    await clientA.publish(localStream);
    await clientA.publish(shareStream, { isAuxiliary: true }); // The shareStream will publish on auxiliary stream by setting the parameter 'isAuxiliary' to true.
    

    Note: If the auxiliary stream contains audio (e.g. screen sharing + system audio), the SDK will mix the audio from the auxiliary stream into the main stream audio to publish the stream, and the remote user need to subscribe main stream for audio playback.

  4. Stopping screen sharing

    // unpublish stream
    await clientA.unpublish(shareStream);
    // close stream
    shareStream.close();
    

    A user may also stop screen sharing by clicking the browser’s built-in button, so it’s necessary to listen for the screen-sharing-stopped event.

    shareStream.on('screen-sharing-stopped', async event => {
      await clientA.unpublish(shareStream);
      shareStream.close();
    });
    
  5. Capturing System Audio During Screen Sharing

    System audio capturing is supported on Chrome M74+ only.

    • On Chrome for Windows and Chrome OS, you can capture the audio of the entire system
    • On Chrome for Linux and macOS, you can capture only the audio of Chrome tabs.
    • Other Chrome versions, OS, and browsers do not support system audio capturing.
    // Set screenAudio to true when creating the screen sharing stream. Don’t set audio and screenAudio both to true at the same time.
    const shareStream = TRTC.createStream({ userId, screenAudio: true, screen: true });
    ...
    

    In the dialog box that pops up, check Share audio, and the stream published will contain system audio.

Attention

  1. A room can only publish one auxiliary stream.
  2. SDK use 1080p profile to capture screen sharing by default, refer to the interface: LocalStream.setScreenProfile.
  3. Starting from v4.15.0, screen sharing streams support publishing stream as auxiliary stream, the following differences need to be noted.
  • In versions before v4.15.0, screen sharing streams were publish as main stream. The return value of RemoteStream.getType() for other Web user is 'main'. The business side needs to use RemoteStream.getUserId() to identify whether the remoteStream is a screen sharing stream or not.
  • In v4.15.0+ version.

Notes