Mac端实现屏幕共享

更新时间:
复制为 MD 格式

本文将为您介绍Mac端如何实现屏幕共享。

功能介绍

屏幕共享功能允许用户在视频通话、直播过程中将自己的屏幕内容实时分享给频道内的其他用户,实现信息的即时共享与可视化交流。

前提条件

在实现屏幕共享前,请确保达成以下条件:

注意事项

  • ARTC 7.6 版本之前开启屏幕共享之前需要入会,入会流程请参考实现音视频通话

  • 7.6版本之后不需要入会就可以开启屏幕共享,建议先设置AliEngineScreenShareConfig.isPushStreamFALSE,待入会之后设置为TRUE,调用updateScreenShareConfig开启推流。

功能实现

1.配置屏幕共享编码参数

如果需要自定义屏幕共享视频流的编码属性,可以调用setScreenShareEncoderConfiguration接口进行配置,包含分辨率、帧率、码率、GOP、视频旋转方向。

说明
  • 该接口在加入频道前后均可配置,如果每次入会只需要设置一次屏幕流视频编码属性,建议在入会前调用。

  • 如果需要更新配置,可以多次调用该接口。

相关配置如下:

参数名

参数说明

默认值

dimensions

视频分辨率。

0x0,表示推流分辨率跟随屏幕采集的分辨率。最大取值为3840x2160。

frameRate

视频帧率。

默认帧率为 5,最大取值为 30。

bitrate

视频编码码率(Kbps)。

注意:码率设置根据分辨率和帧率有对应的合理范围,该值设置在合理范围内有效,否则SDK会自动调节码率到有效值。

512

keyFrameInterval

关键帧间隔,GOP。单位为毫秒(ms)。

默认值0,表示SDK内部控制关键帧间隔。

forceStrictKeyFrameInterval

是否强制编码器严格按照设置的关键帧间隔产生关键帧。

默认值为 false。

  • false表示编码器会响应他人入会等关键帧请求,关键帧间隔和设置的值不严格匹配。

  • true表示编码器不响应其他关键帧请求,严格按照设置的值产生关键帧。可能会造成订阅者首帧变慢。

rotationMode

推流旋转。

默认值为 AliEngineRotationMode_0。可选择 0、90、180、270 四个角度。

示例代码如下:

/*
  config 为客户定义的配置结构体
*/

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秒

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

encoderConfig.forceStrictKeyFrameInterval = forceStrictKeyFrameInterval_;

[self.mainEngine setScreenShareEncoderConfiguration: encoderConfig];

2.设置屏幕共享画面预览

如果需要预览屏幕共享画面,请调用setLocalViewConfig为屏幕共享流(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. (远端)观看屏幕共享

如果需要观看远端用户的屏幕共享画面,可以在onRemoteTrackAvailableNotify回调中为屏幕共享画面setRemoteViewConfig设置显示视图。

- (void)onRemoteTrackAvailableNotify:(NSString *)uid audioTrack:(AliRtcAudioTrack)audioTrack videoTrack:(AliRtcVideoTrack)videoTrack {
    
    /* 主线程处理UI组件  */
    
    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 {
          /* 查找该用户对应的view */
          canvas.view = self.findView(uid);
          int rv = [self.mainEngine setLocalViewConfig:canvas forTrack:AliRtcVideoTrackScreen]; 
      }

    });

}

4. 枚举所有可共享的桌面

调用getScreenShareSourceInfoWithType获取可共享的窗口或桌面列表。

这个时候会有系统弹窗要求用户开启权限,如果用户不开启后续共享都会报错!

_screenInfoArray = [self.engine getScreenShareSourceInfoWithType:AliRtcScreenShareDesktop];

/* 添加到列表上 */
if (_screenInfoArray) {
    
    for (AliRtcScreenSourceInfo *info in _screenInfoArray) {
        //名称+id
        NSString *showString = [NSString stringWithFormat:@"%@+%@",info.sourceName,info.sourceId];
        [_screenListBox addItemWithObjectValue:showString];
    }
    
}

5. 开启屏幕共享

调用 startScreenShareWithDesktopId开启屏幕共享。

注意:需要配置 config.isPushStream

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

/* 如果需要区域分享 */
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;
}

/* 如果需要立刻推流,设置为true,否则设置为FALSE,
   后面再调用updateScreenShareConfig */

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

/* 设置桌面ID, 从_screenListBox获取id */
int idValue =  [[_screenInfoArray[_screenListBox.indexOfSelectedItem] sourceId] intValue] ;
int r = [self.engine startScreenShareWithDesktopId:idValue config:config];

NSLog(@"startScreenShareWithDesktopId:%d",r);
if ( r != 0 ) {
    // 错误提示
} 

6. (可选)更新配置

如果需要更新屏幕共享的配置,可以调用updateScreenShareConfig进行。

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

/* 如果需要区域分享 */
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;
}

/* 如果需要立刻推流,设置为true,否则设置为FALSE,
   后面再调用updateScreenShareConfig */

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

7. 停止屏幕共享

[self.engine stopScreenShare];

多窗口共享

配置预览窗口、预览和推流这些基本逻辑和上面的屏幕共享一致,这里就不单独列出代码。

1. 显示所有可共享窗口

根据业务需求,选择调用startScreenShareWithWindowId来共享对应窗口或者桌面。

_windowInfoArray = [self.engine getScreenShareSourceInfoWithType:AliRtcScreenShareWindow];


/* 显示到listBox上 */
if (_windowInfoArray) {
    for (AliRtcScreenSourceInfo *info in _windowInfoArray) {
        //名称+id
        NSString *showString = [NSString stringWithFormat:@"%@+%@",info.sourceName,info.sourceId];
        [_windowsListBox addItemWithObjectValue:showString];
    }
}

2. 共享指定窗口

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

/* 如果需要区域分享 */
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;
}


/* 如果需要立刻推流,设置为true,否则设置为FALSE,
   后面如果配置好,可以再次调用updateScreenShareConfig修改推流标记 */

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

/* 设置桌面ID, 从_windowsListBox中获取id */

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

NSLog(@"startScreenShareWithWindowId:%d",r);
if ( r != 0 ) {
    // 错误提示
} 

3.停止共享对应窗口或者桌面

调用stopScreenShare停止共享。

[self.mainEngine stopScreenShare];