本文将为您介绍Mac端如何实现屏幕共享。
功能介绍
屏幕共享功能允许用户在视频通话、直播过程中将自己的屏幕内容实时分享给频道内的其他用户,实现信息的即时共享与可视化交流。
前提条件
在实现屏幕共享前,请确保达成以下条件:
注意事项
ARTC 7.6 版本之前开启屏幕共享之前需要入会,入会流程请参考实现音视频通话。
7.6版本之后不需要入会就可以开启屏幕共享,建议先设置
AliEngineScreenShareConfig.isPushStream为FALSE,待入会之后设置为TRUE,调用updateScreenShareConfig开启推流。
功能实现
1.配置屏幕共享编码参数
如果需要自定义屏幕共享视频流的编码属性,可以调用setScreenShareEncoderConfiguration接口进行配置,包含分辨率、帧率、码率、GOP、视频旋转方向。
该接口在加入频道前后均可配置,如果每次入会只需要设置一次屏幕流视频编码属性,建议在入会前调用。
如果需要更新配置,可以多次调用该接口。
相关配置如下:
参数名 | 参数说明 | 默认值 |
dimensions | 视频分辨率。 | 0x0,表示推流分辨率跟随屏幕采集的分辨率。最大取值为3840x2160。 |
frameRate | 视频帧率。 | 默认帧率为 5,最大取值为 30。 |
bitrate | 视频编码码率(Kbps)。 注意:码率设置根据分辨率和帧率有对应的合理范围,该值设置在合理范围内有效,否则SDK会自动调节码率到有效值。 | 512 |
keyFrameInterval | 关键帧间隔,GOP。单位为毫秒(ms)。 | 默认值0,表示SDK内部控制关键帧间隔。 |
forceStrictKeyFrameInterval | 是否强制编码器严格按照设置的关键帧间隔产生关键帧。 | 默认值为 false。
|
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];