屏幕共享,是指在视频通话或互动直播过程中将屏幕内容以视频的方式分享给其他的观众,以增强互动体验,提高沟通效率。
屏幕共享在如下场景中应用广泛:
请参考 下载示例源码 获取源码。
相关源码请查看 “lib\topics\OtherFunctions\screen_sharing” 目录下的文件。
在实现屏幕共享功能之前,请确保:
屏幕采集时,仅 iOS、Android 平台支持同时采集视频和音频;其他平台仅支持采集视频,如需采集音频,请开发者自行实现相关逻辑。
(必选)Android 在录制屏幕前,会弹窗提示用户是否允许应用录制屏幕,请进行授权。
Android 在使用屏幕录制功能时,请务必 获取用户录制屏幕授权,否则将无法使用该功能。
macOS 调用屏幕共享接口在 macOS 平台会获取相关权限,需要在 “安全性与隐私” 中开启录屏权限与辅助功能权限,如不生效需要将之前的权限删除再次新增。
录屏权限
辅助功能权限
Web 平台安装屏幕共享插件(可选)
仅 Chrome 浏览器支持插件形式的屏幕共享,当开发者使用的浏览器为 Chrome 且版本在 65 ~ 72 之间时,需要执行如下操作安装插件:
Android、iOS、Web 平台忽略此步骤。
SDK 可以通过 getScreenCaptureSources 获取当前可共享的所有窗口信息。
List<ZegoScreenCaptureSourceInfo> list = await ZegoExpressEngine.instance.getScreenCaptureSources(400, 400, 100, 100);
调用 createScreenCaptureSource 接口创建屏幕共享源对象。
// 对于 Android、iOS、Web 平台,sourceId、sourceType 不需要传入,传入也不会导致创建失败
ZegoScreenCaptureSource source = await ZegoExpressEngine.instance.createScreenCaptureSource();
// 对于 windows、macOS 平台 sourceId、sourceType 为必填参数,数据来源于 getScreenCaptureSources 接口获取的数据结果
// ZegoScreenCaptureSource source = await ZegoExpressEngine.instance.createScreenCaptureSource(sourceId: list[0].sourceID, sourceType: list[0].sourceType);
在 Web 平台,setVideoSource、setAudioSource 接口调用生效时机如下:
设置采集源为屏幕共享源,则需要对视频源和音频源进行设置。
SDK 推流的视频源默认为摄像头源,如果需要推屏幕共享源,需要通过 setVideoSource 切换为屏幕共享。
ZegoExpressEngine.instance.setVideoSource(ZegoVideoSourceType.ZegoVideoSourceScreenCapture, instanceID: source.getIndex(), channel: ZegoPublishChannel.Main);
SDK 推流的音频源默认为麦克风源,如果需要推屏幕共享源,需要通过 setAudioSource 进行切换为屏幕共享。
ZegoExpressEngine.instance.setAudioSource(ZegoAudioSourceType.ScreenCapture, channel: ZegoPublishChannel.Main);
有两种屏幕共享方式,分别为应用内屏幕共享和跨应用屏幕共享。
若用户只在应用内共享画面与声音,可以调用 startCapture 接口开启屏幕共享,设置 inApp
属性为 true
。也可调用 broadcastFinished 接口回调屏幕共享结束通知,若屏幕采集失败可接收到失败的原因。
var config = ZegoScreenCaptureConfig(true, true, 100, 100);
source.startCapture(config: config, inApp: true);
跨应用屏幕共享是由 iOS 系统通过 Extension 扩展进程进行录制的,所以需要再额外创建扩展进程,并启动。具体请参考如下实现步骤:
Broadcast Upload Extension 的内存使用限制为 50 MB,请勿在屏幕共享的 Extension 中进行额外的内存分配。
使用 Xcode 打开自己 flutter 工程下面的 iOS 目录下的后缀为 xcworkspace 的 iOS 原生项目工程文件,然后在菜单栏中依次点击 “File > New > Target..."。
在弹出的窗口中选择 iOS 页的 “Broadcast Upload Extension” 后,单击 “Next”。
在弹出的对话框中的 “Product Name” 一栏填写 “Broadcast Upload Extension” 的名字,例如 “ScreenShare”。选择 “Team”、“Language” 等信息后,单击 “Finish” 。
无需勾选 “Include UI Extension”。
创建完成后,您会在项目中看到该 Extension 的文件夹,结构类似如下,该文件夹用于存放屏幕共享功能的实现代码:
确保 Extension 的 “Info.plist” 文件中,将 “RPBroadcastProcessMode” 设置为 “RPBroadcastProcessModeSampleBuffer”。
在 Extension 中导入 ZEGO Express SDK,在 xcode 中点击工程进入工程配置页面。选择上面创建的 Extension,找到 General 下面的 Frameworks and Libraries 项,点击 + 号,选择 ZegoExpressEngine.xcframework 进行添加。
若用户需要共享整个系统的画面与声音,可以调用 startCapture 接口开启屏幕共享。
var config = ZegoScreenCaptureConfig(true, true, 100, 100);
source.startCapture(config: config, inApp: false);
如下系统回调的实现可以在 SDK 的源码中的 “/ios/ScreenShare/SampleHandler.m” 文件中查看:
ZegoReplayKitExt
类中的如下接口创建数据传输通道:[ZegoReplayKitExt.sharedInstance setupWithDelegate:self];
在 processSampleBuffer 系统回调中,通过 ZegoReplayKitExt
类中的 sendSampleBuffer
接口发送给 ZEGO Express SDK。
[ZegoReplayKitExt.sharedInstance sendSampleBuffer:sampleBuffer withType:sampleBufferType];
系统通过 broadcastFinished 回调通知 Extension 屏幕录制已结束,您可以在该回调中,调用 ZegoReplayKitExt
类中的如下接口停止屏幕共享并断开数据传输通道:
[ZegoReplayKitExt.sharedInstance finished];
调用 startCapture 接口共享整个系统的画面。
source.startCapture();
调用 updateCaptureSource 接口可以更新共享窗口画面。
source.updateCaptureSource(list[1].sourceID, list[1].sourceType)
调用 updateCaptureSource 接口可以动态更新共享窗口区域。其中设置为 (0, 0, 0, 0) 可恢复整个窗口共享。
source.updateCaptureRegion(Rect.fromLTWH(10, 10, 400, 400));
调用 setExcludeWindowList 接口可以过滤掉共享的屏幕中指定窗口画面,只适用于共享整个屏幕的时候设置。
source.updateCaptureRegion([list[1].sourceID]);
调用 enableWindowActivate 接口可以激活当前共享的窗口。
source.enableWindowActivate(true);
调用 enableCursorVisible 接口可以显示或隐藏鼠标。
source.enableCursorVisible(true);
采集异常回调 onExceptionOccurred,当有异常回调时,会中断采集。
ZegoExpressEngine.onExceptionOccurred = (ZegoScreenCaptureSource source,
ZegoScreenCaptureSourceExceptionType exceptionType) {
};
ZegoExpressEngine.onMobileScreenCaptureStart = () {
};
ZegoExpressEngine.onMobileScreenCaptureExceptionOccurred = (ZegoScreenCaptureSourceExceptionType exceptionType) {
};
调用 loginRoom 接口,传入房间 ID 参数 “roomID” 和用户参数 “user”,登录房间。
调用 startPublishingStream 接口,传入流 ID 参数 “streamID”,向远端用户发送本端的音视频流。
// 创建用户
var user = new ZegoUser.id("user1");
// 开始登录房间
ZegoExpressEngine.instance.loginRoom("room1", user);
// 开始推流
ZegoExpressEngine.instance.startPublishingStream("stream1");
至此,我们已完成采集屏幕数据并通过 ZEGO Express SDK 分享到远端的操作。
完成以上步骤之后,其他用户可以使用 startPlayingStream 接口拉取屏幕共享流。
// 拉流播放,需传入发起屏幕共享的用户推流时所用的 streamID
ZegoExpressEngine.instance.startPlayingStream(streamID, canvas: ZegoCanvas.view(playView));
调用 stopCapture 接口停止共享。
source.stopCapture();
联系我们
文档反馈