All Products
Search
Document Center

ApsaraVideo Live:Implement screen sharing on macOS

Last Updated:Mar 20, 2026

This topic describes how to implement screen sharing on macOS.

Function Introduction

Screen sharing lets you share your screen content in real time with other users in a channel during a video call or live stream. This feature enables instant information sharing and visual communication.

Prerequisites

Before you implement screen sharing, ensure that the following prerequisites are met:

  • You have a valid Alibaba Cloud account and have created an ApsaraVideo Real-time Communication application. For more information, see Create an application. You can obtain the App ID and App Key from the console.

  • You have integrated the ApsaraVideo Real-time Communication (ARTC) SDK into your project and implemented basic real-time audio and video features. For more information about SDK integration, see SDK download and integration. For more information about audio and video implementation, see Implement audio and video calls.

Notes

  • In ARTC versions earlier than 7.6, you must join a channel before you start screen sharing. For more information about how to join a channel, see Implement audio and video calls.

  • In ARTC 7.6 and later, you can start screen sharing without joining a channel. We recommend that you set AliEngineScreenShareConfig.isPushStream to FALSE. After you join the channel, set the parameter to TRUE and call the updateScreenShareConfig method to start stream ingest.

Implementation

1. Configure screen sharing encoding parameters

To customize the encoding properties of the screen sharing video stream, call the setScreenShareEncoderConfiguration method. You can configure parameters such as resolution, frame rate, bitrate, Group of Pictures (GOP), and video rotation.

Note
  • You can call this method before or after you join a channel. To set the screen stream encoding properties only once per session, we recommend that you call this method before you join the channel.

  • You can call this method multiple times to update the configuration as needed.

The related configurations are as follows:

Parameter name

Description

Default value

dimensions

The video resolution.

0 × 0. This value indicates that the ingest resolution matches the captured screen resolution. The maximum value is 3840 × 2160.

frameRate

The video frame rate.

The default value is 5. The maximum value is 30.

bitrate

The video encoding bitrate. Unit: Kbps.

Note The bitrate must be within a reasonable range based on the resolution and frame rate. If the specified value is outside the valid range, the SDK automatically adjusts it to a valid value.

512

keyFrameInterval

The keyframe interval, also known as the Group of Pictures (GOP). Unit: milliseconds (ms).

The default value is 0. This value indicates that the SDK internally controls the keyframe interval.

forceStrictKeyFrameInterval

Specifies whether to force the encoder to strictly follow the configured keyframe interval.

The default value is false.

  • false: The encoder responds to keyframe requests, such as when a new user joins. In this case, the actual interval may differ from the configured value.

  • true: The encoder ignores external keyframe requests and strictly adheres to the configured interval. This may delay the rendering of the first frame for subscribers.

rotationMode

The rotation of the video stream.

The default value is AliEngineRotationMode_0. Valid values are 0, 90, 180, and 270.

Sample code:

/*
  config is a user-defined configuration struct
*/

AliRtcScreenShareEncoderConfiguration * encoderConfig = [[AliRtcScreenShareEncoderConfiguration alloc] init];

encoderConfig.dimensions = CGSizeMake( width_, height_);
encoderConfig.frameRate = frameRate_;   // 5/10/15...
encoderConfig.bitrate = bitrate_;	// 1200...
encoderConfig.rotation = AliRtcRotationMode_0; // 0/90/180/270
encoderConfig.keyFrameInterval = keyFrameInterval_; // 1/2/3 seconds

if (keyFrameInterval_ > 0) {
    encoderConfig.forceStrictKeyFrameInterval = TRUE;
}

encoderConfig.forceStrictKeyFrameInterval = forceStrictKeyFrameInterval_;

[self.mainEngine setScreenShareEncoderConfiguration: encoderConfig];

2. Set up screen sharing preview

To preview the local screen sharing feed, call the setLocalViewConfig method to set the display view for the screen sharing stream (AliEngineVideoTrackScreen).

AliVideoCanvas *canvas = [[AliVideoCanvas alloc]init];
canvas.mirrorMode = _mirrorButton.state == NSControlStateValueOn ? AliRtcRenderMirrorModeAllEnabled:AliRtcRenderMirrorModeAllDisabled;
canvas.view = renderView;
int rv = [self.mainEngine setLocalViewConfig:canvas forTrack:AliRtcVideoTrackScreen];

3. (Remote) View screen sharing

To view the screen sharing feed of a remote user, you can call the setRemoteViewConfig method in the onRemoteTrackAvailableNotify callback to set the display view.

- (void)onRemoteTrackAvailableNotify:(NSString *)uid audioTrack:(AliRtcAudioTrack)audioTrack videoTrack:(AliRtcVideoTrack)videoTrack {
    
    /* Handle UI components on the main thread */
    
    dispatch_async(dispatch_get_main_queue(), ^{
      AliVideoCanvas *canvas = [[AliVideoCanvas alloc]init];
      if ( videoTrack == AliRtcVideoTrackScreen ) {
          canvas.view = self._screenshareView;
          int rv = [self.mainEngine setLocalViewConfig:canvas forTrack:AliRtcVideoTrackScreen]; 
      } else {
          /* Find the view corresponding to this user */
          canvas.view = self.findView(uid);
          int rv = [self.mainEngine setLocalViewConfig:canvas forTrack:AliRtcVideoTrackScreen]; 
      }

    });

}

4. Enumerate all shareable desktops

Call the getScreenShareSourceInfoWithType method to obtain a list of shareable windows and desktops.

A system prompt appears to request permission. If the user denies the permission, all subsequent sharing attempts fail.

_screenInfoArray = [self.engine getScreenShareSourceInfoWithType:AliRtcScreenShareDesktop];

/* Add to list */
if (_screenInfoArray) {
    
    for (AliRtcScreenSourceInfo *info in _screenInfoArray) {
        // Name + ID
        NSString *showString = [NSString stringWithFormat:@"%@+%@",info.sourceName,info.sourceId];
        [_screenListBox addItemWithObjectValue:showString];
    }
    
}

5. Start screen sharing

Call the startScreenShareWithDesktopId method to start screen sharing.

Note You must configure config.isPushStream.

AliRtcScreenShareConfig *config = [[AliRtcScreenShareConfig alloc]init];

/* For region-based sharing */
if ( shareRegion ) {
    
    config.isShareByRegion = TRUE ;
    AliRtcScreenShareRegion *region = [[AliRtcScreenShareRegion alloc]init];
    region.originX = regionRect.origin.x;
    region.originY = regionRect.origin.y;
    region.width = regionRect.size.width;
    region.height = regionRect.size.height;
    
    config.shareRegion = region;
    
} else {
    config.isShareByRegion = FALSE;
}

/* Set to true to push stream immediately; otherwise, set to FALSE
   and call updateScreenShareConfig later */

if ( pushStream ) {
    config.isPushStream = TRUE ;
} else {
    config.isPushStream = FALSE ;
}

/* Set desktop ID from _screenListBox */
int idValue =  [[_screenInfoArray[_screenListBox.indexOfSelectedItem] sourceId] intValue] ;
int r = [self.engine startScreenShareWithDesktopId:idValue config:config];

NSLog(@"startScreenShareWithDesktopId:%d",r);
if ( r != 0 ) {
    // Error handling
} 

6. (Optional) Update configuration

To update the screen sharing configuration, call the updateScreenShareConfig method.

AliRtcScreenShareConfig *config = [[AliRtcScreenShareConfig alloc]init];

/* For region-based sharing */
if ( share_region ) {
    
    config.isShareByRegion = TRUE ;
    AliRtcScreenShareRegion *region = [[AliRtcScreenShareRegion alloc]init];
    region.originX = regionRect.origin.x;
    region.originY = regionRect.origin.y;
    region.width = regionRect.size.width;
    region.height = regionRect.size.height;
    
    config.shareRegion = region;
    
} else {
    config.isShareByRegion = FALSE;
}

/* Set to true to push stream immediately; otherwise, set to FALSE
   and call updateScreenShareConfig later */

if ( pushStream ) {
    config.isPushStream = TRUE ;
} else {
    config.isPushStream = FALSE ;
}
      
[self.engine updateScreenShareConfig:mScreenConfig];

7. Stop screen sharing

[self.engine stopScreenShare];

Multi-window sharing

The logic for configuring preview views, previewing, and ingesting streams is the same as that for desktop sharing. The sample code is not repeated in this section.

1. Display all shareable windows

Based on your business requirements, you can call the startScreenShareWithWindowId method to share a specific window.

_windowInfoArray = [self.engine getScreenShareSourceInfoWithType:AliRtcScreenShareWindow];


/* Display in listBox */
if (_windowInfoArray) {
    for (AliRtcScreenSourceInfo *info in _windowInfoArray) {
        // Name + ID
        NSString *showString = [NSString stringWithFormat:@"%@+%@",info.sourceName,info.sourceId];
        [_windowsListBox addItemWithObjectValue:showString];
    }
}

2. Share a specific window

AliRtcScreenShareConfig *config = [[AliRtcScreenShareConfig alloc]init];

/* For region-based sharing */
if ( shareRegion ) {
    
    config.isShareByRegion = TRUE ;
    AliRtcScreenShareRegion *region = [[AliRtcScreenShareRegion alloc]init];
    region.originX = regionRect.origin.x;
    region.originY = regionRect.origin.y;
    region.width = regionRect.size.width;
    region.height = regionRect.size.height;
    
    config.shareRegion = region;
    
} else {
    config.isShareByRegion = FALSE;
}


/* Set to true to push stream immediately; otherwise, set to FALSE.
   Later, call updateScreenShareConfig to modify the push stream flag */

if ( pushStream ) {
    config.isPushStream = TRUE ;
} else {
    config.isPushStream = FALSE ;
}

/* Set window ID from _windowsListBox */

int idValue =  [[_windowInfoArray[_windowsListBox.indexOfSelectedItem] sourceId] intValue] ;
int r = [self.engine startScreenShareWithWindowId:idValue config:config];

NSLog(@"startScreenShareWithWindowId:%d",r);
if ( r != 0 ) {
    // Error handling
} 

3. Stop sharing a window or desktop

Call the stopScreenShare method to stop sharing.

[self.mainEngine stopScreenShare];