You need to enable JavaScript to run this app.
文档中心
实时音视频

实时音视频

复制全文
下载 pdf
屏幕共享
iOS 端屏幕共享
复制全文
下载 pdf
iOS 端屏幕共享
在实时通信中,如果你希望用户可以分享本端设备的屏幕和设备播放的音频,可以使用 RTC 内建的屏幕采集功能,也可以自行实现屏幕采集逻辑(自定义采集),并通过屏幕共享功能,与远端用户共享。​
仅可见的用户可以发布屏幕流。​
适用场景​
你可以在多种行业、多种场景下使用屏幕共享功能:​
​
​
行业​
场景​
在线教育​
老师共享屏幕给学生上课;美术老师共享屏幕给学生教画画。​
游戏直播​
主播共享屏幕给观众,展现自己的游戏画面。​
互动直播​
主播共享自己的屏幕和观众互动。​
视频会议​
会议成员共享屏幕观看 PPT 或者文档。​
​
前提条件​
  • 支持的操作系统:iOS 12 及以上版本​
其中,iOS 12 ~ iOS 12.2 之间版本需要集成 RTC SDK v3.52 或更高版本。​
功能实现​
​Image​​
iOS 端基于苹果提供的 Replaykit 框架实现屏幕录制,可以分享整个系统的屏幕内容。但由于苹果的隐私设置,不同 App 之间数据无法互通,因此需要当前 App(主 App 进程)额外提供一个 Extension 扩展组件(Extension 进程),并且把 App 和 Extension 配置为同一 App Group,让 Extension 录屏进程可以同主 App 进程进行跨进程通信,实现屏幕内容分享。​
步骤一:创建并配置 App Group​
为使 Extension 录屏进程可以和主 App 进程进行跨进程通信,需要将 Extension 和 App 配置为同一 App Group。参看如何创建和配置 App Group。​
步骤二:创建 Extension 扩展组件​
新建 Broadcast Upload Extension 组件并进行相关配置。​
  1. 在 Xcode 中,点击 File > New > Target...,在弹出对话框中选择 Broadcast Upload Extension,点击 Next。​
  • ​Image​​
  1. 填写相关信息,取消勾选 “Include UI Extension”,点击 Finish 完成创建。​
RTC 暂不支持 Broadcast Setup UI Extension。如需开启该扩展,请确认已自行实现相关逻辑。​
  1. 选择刚创建的 Target 进行配置。新建 Target 的 Bundle Identifier 必须以主 App target 的 Bundle Identifier 为前缀。​
  1. 将 RTC SDK 的屏幕共享插件引入到工程中。你可以下载 iOS SDK 包,将其中的 VolcEngineRTCScreenCapturer.framework 文件拖动到工程中,也可以在项目 Podfile 文件添加如下代码:​
  • ​
    target 'ScreenShareExtension' do​
    use_frameworks!​
    pod 'VolcEngineRTC', '3.xx.xx', :subspecs => ['ScreenCapture']​
    end​
    ​
步骤三:在 Extension 组件中实现屏幕采集逻辑​
参考如下代码在 SampleHandler.m 文件中实现屏幕采集逻辑。在新创建的 Target 中,Xcode 将自动创建 SampleHandler.h 文件。​
​
#import "SampleHandler.h"​
#import <VolcEngineRTCScreenCapturer/ByteRTCScreenCapturerExt.h>​
​
@interface SampleHandler () <ByteRtcScreenCapturerExtDelegate>​
​
@end​
​
@implementation SampleHandler​
​
- (void)broadcastStartedWithSetupInfo:(NSDictionary<NSString *,NSObject *> *)setupInfo {​
// 填写步骤一中创建的 App Group ID​
NSString *groupId = @"xxxxxxxxx";​
// 开始屏幕采集​
[[ByteRtcScreenCapturerExt shared] startWithDelegate:self groupId:groupId];​
}​
​
- (void)broadcastPaused {​
// User has requested to pause the broadcast. Samples will stop being delivered.​
}​
​
- (void)broadcastResumed {​
// User has requested to resume the broadcast. Samples delivery will resume.​
}​
​
- (void)broadcastFinished {​
// User has requested to finish the broadcast.​
// 结束屏幕采集​
[[ByteRtcScreenCapturerExt shared] stop];​
}​
​
- (void)processSampleBuffer:(CMSampleBufferRef)sampleBuffer withType:(RPSampleBufferType)sampleBufferType {​
​
switch (sampleBufferType) {​
case RPSampleBufferTypeVideo:// 采集到的屏幕视频流​
case RPSampleBufferTypeAudioApp:// 采集到的设备音频流​
[[ByteRtcScreenCapturerExt shared] processSampleBuffer:sampleBuffer withType:sampleBufferType];​
break;​
case RPSampleBufferTypeAudioMic:​
// 采集到的麦克风音频流​
break;​
​
default:​
break;​
}​
}​
​
#pragma mark - ByteRtcScreenCapturerExtDelegate​
// 通知 Broadcast Upload Extension 停止采集屏幕并退出。​
- (void)onQuitFromApp {​
NSDictionary *dic = @{​
NSLocalizedFailureReasonErrorKey : @"您停止了屏幕共享"};​
NSError *error = [NSError errorWithDomain:RPRecordingErrorDomain​
code:RPRecordingErrorUserDeclined​
userInfo:dic];​
[self finishBroadcastWithError:error];​
}​
​
@end​
​
步骤四:为 RTC Engine 设置 App Group ID​
创建 RTC 引擎后,调用 setExtensionConfig: 接口,填写步骤一中创建的 App Group ID,以响应从系统的控制中心发起的屏幕共享。​
​
- (void)initEngineAndJoinRoom{​
// 创建引擎 ​
self.rtcEngine = [ByteRTCEngine createRTCEngine:APPID delegate:self parameters:@{}];​
// 填写步骤一中创建的 App Group ID​
[self.rtcEngine setExtensionConfig:APP_GROUP];​
}​
​
步骤五:调用 RTC 接口共享屏幕​
内部采集​
接口调用时序如下图:​
​Image​​
【可选】设置编码参数​
如果默认的编码参数不能满足你的要求,你可以在开始屏幕采集前,通过 setVideoEncoderConfig 方法设置编码参数。​
  • RTC 对屏幕源进行缩放时,不会改变原始宽高比。当宽高与源分辨率不一致时,​
  • 如果源分辨率大于目标分辨率,录制视频将被等比例缩小。​
  • 如果源分辨率小于目标分辨率,录制分辨率保持不变。​
  • 当宽高均为默认值 0 时,录制分辨率保持不变。但是,如果屏幕物理分辨率长边高于 1920 px,录制视频将被等比例缩小,长边将被缩小到 1920。​
开启屏幕采集​
方式一:在代码中开启采集。​
​
- (void)startScreenShare {​
// 设置屏幕流视频参数(可选)​
ByteRTCVideoEncoderConfig * config = [[ByteRTCVideoEncoderConfig alloc] init];​
config.width = 360;​
config.height = 640;​
config.frameRate = 15;​
config.maxBitrate = 500000;​
config.minBitrate = 0;​
[self.rtcEngine setVideoEncoderConfig:config];​
​
// 开启屏幕共享​
[self.rtcEngine startScreenCapture:ByteRTCScreenMediaTypeVideoAndAudio bundleId:EXTENSION_BUNDLE_ID];​
}​
​
方式二:从系统控制中心发起。​
  1. 在 iOS 系统的控制中心,长按录屏按钮​
  1. 在弹窗中选择你的应用,点击 开始直播,开始录屏​
​Image​​
本端自定义采集屏幕视频流​
RTC 强烈建议你使用内部采集。如果你仍然希望使用自定义采集,参看以下步骤。​
  1. 实现屏幕音视频流采集逻辑。​
  1. 指定为外部输入源。​
  1. 调用 pushScreenAudioFrame: 将采集得到的音视频帧推送到 RTC SDK 用于编码传输。​
本端发布/停止发布屏幕流​
(可选)本端实现回调方法 onVideoDeviceStateChanged。此步骤不需要调用关于屏幕采集的 API,只需要更新相关 UI。​
​
// 在 ByteRTCEngineDelegate 中,发布与停止发布屏幕流​
- (void)rtcEngine:(ByteRTCEngine *)engine onVideoDeviceStateChanged:(NSString *)device_id device_type:(ByteRTCVideoDeviceType)device_type device_state:(ByteRTCMediaDeviceState)device_state device_error:(ByteRTCMediaDeviceError)device_error {​
if (device_type == ByteRTCVideoDeviceTypeScreenCaptureDevice && self.preJoinSetting.isScreenShare) {​
​
if (device_state == ByteRTCMediaDeviceStateStarted) {​
dispatch_async(dispatch_get_main_queue(), ^{​
self.localView.uid = @"正在共享";​
self.screenShareBtn.selected = YES;​
self.screenShareBtn.imageView.backgroundColor = UIColor.clearColor;​
});​
} else if (device_state == ByteRTCMediaDeviceStateStopped ||​
device_state == ByteRTCMediaDeviceStateRuntimeError) {​
dispatch_async(dispatch_get_main_queue(), ^{​
self.localView.uid = @"等待屏幕共享";​
self.screenShareBtn.selected = NO;​
self.screenShareBtn.imageView.backgroundColor = UIColor.lightGrayColor;​
});​
}​
}​
}​
​
远端渲染和移除屏幕流​
您可在远端使用 onUserPublishStreamVideo 和 onFirstRemoteVideoFrameDecoded 回调监视视频流和屏幕共享流。建议您在 onFirstRemoteVideoFrameDecoded 回调中设置视频渲染,确保视频渲染在视频解码完成后进行,以避免卡顿。​
​
- (void)rtcEngine:(ByteRTCEngine * _Nonnull)engine onFirstRemoteVideoFrameDecoded:(NSString * _Nonnull)streamId info:(ByteRTCStreamInfo* _Nonnull)info withFrameInfo:(ByteRTCVideoFrameInfo * _Nonnull)frameInfo {​
self.userIdStreamInfoMap[info.userId] = info; // 保存流相关信息​
dispatch_async(dispatch_get_main_queue(), ^{​
UIView *view = [[UIView alloc] init];​
ByteRTCVideoCanvas *canvas = [[ByteRTCVideoCanvas alloc] init];​
canvas.view = view;​
canvas.renderMode = ByteRTCRenderModeHidden;​
[self.rtcEngine setRemoteVideoCanvas:streamId withCanvas:canvas];​
​
UserLiveView *liveView = [[UserLiveView alloc] init];​
liveView.uid = info.userId;​
liveView.view = view;​
[self.containerView addSubview:liveView];​
});​
}​
​
- (void)rtcRoom:(ByteRTCRoom* _Nonnull)rtcRoom onUserPublishStreamVideo:(NSString* _Nonnull)streamId info:(ByteRTCStreamInfo* _Nonnull)info isPublish:(BOOL)isPublish {​
if (!isPublish) {​
[self.userIdStreamInfoMap[info.userId] removeObjectForKey:info.userId]; // 移除流相关信息​
dispatch_async(dispatch_get_main_queue(), ^{​
for (UserLiveView *liveView in self.containerView.subviews) {​
if ([userId isEqualToString:liveView.uid]) {​
liveView.uid = @"";​
}​
}​
});​
}​
}​
​
本端停止屏幕共享​
​
- (void)stopScreenShare {​
// 停止使用 RTC SDK 内部采集方式采集屏幕音视频​
[self.rtcEngine stopScreenCapture];​
}​
​
常见问题​
  1. App 进入后台后,如何防止共享中断?​
屏幕共享依赖于主进程向 RTC 服务端发布媒体流,建议采用播放静音文件等,在 App 进入后台进行保活。​
  1. 如何以 pod 形式引入?​
  • 其中,3.xx.xxx 为 RTC SDK 的版本号。​
  • ​
    source 'https://github.com/volcengine/volcengine-specs.git'​
    target 'your target' do​
    pod 'VolcEngineRTC', '3.xx.xxx'​
    end​
    ​
    // 屏幕共享模块​
    target 'ScreenShareExtension' do​
    use_frameworks!​
    pod 'VolcEngineRTC', '3.xx.xxx', :subspecs => ['ScreenCapture']​
    end​
    ​
API 参考​
功能变更日志​
本文最近更新时的 SDK 版本为 3.60。如果你使用的 SDK 为之前版本,请查看以下变动,并进行相应适配。​
  • 在 3.60 单路流版本中,存在如下变动:​
  • createRTCVideo 接口已变更为 createRTCEngine。​
  • publishScreen 和 unpublishScreen 接口已不存在。请使用 publishStreamVideo 和 publishStreamAudio 控制是否发布音视频。如果您已经调用 startScreenCapture,那么设置 publishStreamVideo(true) 将会直接开始发布屏幕流。​
  • 在屏幕准备好后,您会收到 onVideoDeviceStateChanged 回调。​
  • onUserUnPublishScreen 回调已不存在。请使用 onUserPublishStreamVideo 回调替代。使用 streamInfo.isScreen 来判断是否为屏幕流。​
  • 3.50.1 版本中​
  • 设置共享流的编码参数类型名称变更为 ByteRTCScreenVideoEncoderConfig。​
  • 自定义屏幕流相关的接口名称和行为有变更。​
  • 3.43.1 版本中​
  • publishScreen: 和 unpublishScreen: 的类名由 ByteRTCEngineKit 变更为 RTCRoom。其他方法的类名变更为 RTCVideo。​
  • 回调类名由 ByteRTCEngineDelegate 变更为 RTCVideoDelegate。​
  • 3.36.1 版本中​
  • 设置共享流的编码参数方法由 SetVideoEncoderConfig: 变更为 SetScreenVideoEncoderConfig:。​
  • PublishScreen: 等 API 的参数有变更。​
​
最近更新时间:2026.09.22 15:59:54
这个页面对您有帮助吗?
有用
有用
无用
无用