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

实时音视频

复制全文
下载 pdf
屏幕共享
Android 端屏幕共享
复制全文
下载 pdf
Android 端屏幕共享
在实时通信中,如果你希望用户可以分享本端设备的屏幕和设备播放的音频,可以使用 RTC 内建的屏幕采集功能,也可以自行实现屏幕采集逻辑(自定义采集),并通过屏幕共享功能,与远端用户共享。​
在使用屏幕共享功能时,仅可见的用户可以发布屏幕流。​
适用场景​
你可以在多种行业、多种场景下使用屏幕共享功能:​
​
​
行业​
场景​
在线教育​
老师共享屏幕给学生上课;美术老师共享屏幕给学生教画画。​
游戏直播​
主播共享屏幕给观众,展现自己的游戏画面。​
互动直播​
主播共享自己的屏幕和观众互动。​
视频会议​
会议成员共享屏幕观看 PPT 或者文档。​
​
功能实现​
Android 端屏幕共享基于 Android 5 (API 级别 21) 中引入的媒体投影 API 和 RTC 提供的 API 共同实现。​
前提条件​
  • Android 5.0 (API 级别 21) 及以上版本。推荐使用 Android 10 (API 级别 29) 及以上版本。​
说明​
  • 在使用屏幕共享功能期间,如果您切换到带有 DRM 版权保护(如爱奇艺、Netflix 等流媒体播放器)或应用层主动设置了禁止录屏截屏标志(如部分银行 App 的密码输入界面)的应用,RTC 的屏幕共享模块将无法获取到这些应用的画面内容,接收端可能会看到纯黑屏。​
  • Android 5.0 ~ 10 版本仅支持屏幕视频采集,不支持屏幕音频采集。​
接入流程​
工程配置​
Android 10 (API 级别 29) 及以上进行屏幕采集需要用到前台服务,在应用的 Android 清单文件中添加如下前台服务声明。​
录音权限声明已包含在 RTC SDK 中,App 清单文件无需添加。​
​
<application>​
...​
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />​
...​
​
<service​
android:name="com.ss.bytertc.base.media.screen.RXScreenCaptureService"​
android:enabled="true"​
android:exported="false"​
android:foregroundServiceType="mediaProjection" />​
</application>​
​
Android 14(API 级别 34)及以上还需声明如下权限,以免出现应用闪退等异常:​
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />​
权限申请​
向系统请求屏幕共享的权限。​
​
public static final int REQUEST_CODE_OF_SCREEN_SHARING = 101;​
​
// 向系统发起屏幕共享的权限请求​
public void requestForScreenSharing() {​
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {​
Log.e("ShareScreen","当前系统版本过低,无法支持屏幕共享");​
return;​
}​
MediaProjectionManager projectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);​
if (projectionManager != null) {​
startActivityForResult(projectionManager.createScreenCaptureIntent(), REQUEST_CODE_OF_SCREEN_SHARING);​
} else {​
Log.e("ShareScreen","当前系统版本过低,无法支持屏幕共享");​
}​
}​
​
在权限申请的响应中,开启屏幕共享。​
​
public static final int REQUEST_CODE_OF_SCREEN_SHARING = 101;​
​
@Override​
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {​
if (requestCode == REQUEST_CODE_OF_SCREEN_SHARING && resultCode == Activity.RESULT_OK) {​
startScreenShare(data);​
} else {​
super.onActivityResult(requestCode, resultCode, data);​
}​
}​
​
API 调用​
  1. 本端开启屏幕采集并开始共享屏幕​
​
private void startScreenShare(Intent data) {​
startRXScreenCaptureService(data);​
// 编码参数​
ScreenVideoEncoderConfig config = new ScreenVideoEncoderConfig();​
config.width = 720;​
config.height = 1280;​
config.frameRate = 15;​
config.maxBitrate = 1600;​
mRTCEngine.setScreenVideoEncoderConfig(config);​
​
// 开启屏幕视频数据采集​
// 如果在进入房间的时候设置了 isAutoPublishVideo = true,那么此步骤将直接开始屏幕共享。​
// 否则,您需要调用 publishStreamVideo(true) 来开始共享屏幕。​
mRTCEngine.startScreenCapture(ScreenMediaType.SCREEN_MEDIA_TYPE_VIDEO_AND_AUDIO, data);​
}​
​
private void startRXScreenCaptureService(@NonNull Intent data) {​
Context context = Utilities.getApplicationContext();​
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {​
Intent intent = new Intent();​
intent.putExtra(RXScreenCaptureService.KEY_LARGE_ICON, R.drawable.launcher_quick_start);​
intent.putExtra(RXScreenCaptureService.KEY_SMALL_ICON, R.drawable.launcher_quick_start);​
intent.putExtra(RXScreenCaptureService.KEY_LAUNCH_ACTIVITY, mHostActivity.getClass().getCanonicalName());​
intent.putExtra(RXScreenCaptureService.KEY_CONTENT_TEXT, "正在录制/投射您的屏幕");​
intent.putExtra(RXScreenCaptureService.KEY_RESULT_DATA, data);​
context.startForegroundService(RXScreenCaptureService.getServiceIntent(context, RXScreenCaptureService.COMMAND_LAUNCH, intent));​
}​
}​
​
  1. (可选)本端在 IRTCEngineEventHandler 实现类的回调方法 onVideoDeviceStateChanged 。此步骤不需要调用关于屏幕采集的 API,只需要更新相关 UI。​
​
@Override​
public void onVideoDeviceStateChanged(String deviceId, VideoDeviceType deviceType, int deviceState, int deviceError) {​
Log.i(TAG, "onVideoDeviceStateChanged, type: " + deviceType + " state:" + deviceState);​
}​
​
  1. 远端使用 onUserPublishStreamVideo 和 onFirstRemoteVideoFrameDecoded 回调监视视频流和屏幕共享流。建议您在 onFirstRemoteVideoFrameDecoded 回调中设置视频渲染,确保视频渲染在视频解码完成后进行,以避免卡顿。​
​
// 房间内远端屏幕共享音视频流移除的回调。​
​
@Override​
public void onFirstRemoteVideoFrameDecoded(String streamId, StreamInfo streamInfo, VideoFrameInfo frameInfo) {​
Log.i(TAG, "onFirstRemoteVideoFrameDecoded, streamId: " + streamId);​
runOnUiThread(() -> {​
// 设置远端视频渲染视图​
setRemoteRenderView(streamId);​
});​
}​
​
@Override​
public void onUserPublishStreamVideo(String streamId, StreamInfo streamInfo, boolean isPublish) {​
if (!isPublish) {​
Log.i(TAG, "onUserUnpublishStreamVideo, uid: " + streamId);​
runOnUiThread(() -> {​
// 解除远端视频渲染视图绑定​
removeRemoteView(streamId);​
});​
}​
}​
​
  1. 远端渲染屏幕共享流​
​
private void setRemoteRenderView(String streamId, String roomID, String userID, FrameLayout container) {​
TextureView renderView = new TextureView(this);​
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(​
ViewGroup.LayoutParams.MATCH_PARENT,​
ViewGroup.LayoutParams.MATCH_PARENT);​
container.removeAllViews();​
container.addView(renderView, params);​
​
VideoCanvas videoCanvas = new VideoCanvas();​
videoCanvas.renderView = renderView;​
videoCanvas.renderMode = VideoCanvas.RENDER_MODE_HIDDEN;​
​
// 设置远端用户视频渲染视图​
mRTCEngine.setRemoteVideoCanvas(streamId, videoCanvas);​
}​
​
  1. 本端停止屏幕共享​
​
private void stopScreenShare() {​
// 停止屏幕数据采集和屏幕共享​
mRTCEngine.stopScreenCapture();​
}​
​
自定义采集屏幕视频流​
RTC 强烈建议你使用内部采集。如果你仍然希望使用自定义采集,参看以下步骤。​
  1. 实现屏幕音视频流采集逻辑。​
  1. 指定为外部输入源。调用 setVideoSourceType 设置屏幕视频自定义采集。​
  1. 调用 pushScreenAudioFrame 将采集得到的音频帧推送到 RTC SDK 用于编码传输。​
常见问题​
  1. 共享屏幕后,对端只能看到画面,听不到音频。​
  • 当前的系统版本低于 Android 10,系统不支持屏幕音频采集。​
  • 其他 App 独占了屏幕音频捕获。切换至其他 App,查看是否开启了独占设置。​
  • 已向系统申请录制权限,并在使用中允许录制请求。​
  1. 收到以下错误提示:​
  • Media projections require a foreground service of type ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION​
  • 原因和解决方法如下:​
  • 在 AndroidManifest.xml 中配置 android.permission.FOREGROUND_SERVICE 权限和 com.ss.bytertc.base.media.screen.RXScreenCaptureService 声明。​
  • 检查启动 RXScreenCaptureService 时,RXScreenCaptureService.KEY_LAUNCH_ACTIVITY 是否传入了全类名。 由于启动流程中开启 notification 时,需要获取全类名,以通过反射获取相关联的 activity,非全类名将导致 notification 创建失败,并收到上述错误提示。​
  1. 没有实现功能,且无其他错误提示。​
  • 检查启动 RXScreenCaptureService 时,RXScreenCaptureService.KEY_RESULT_DATA 是否传入 。​
  • 在Android 清单文件中增加前台服务声明​
  • 在代码中启动前台服务​
  • 请求录制权限的结果需要作为参数传递给前台服务​
  1. 使用 Android 5.0 ~ 10 版本 设备进行屏幕共享后自动断开。​
  • 上述系统版本的个别 Android 机型可能存在兼容性问题。建议用户升级系统版本。​
功能变更日志​
本文最近更新时的 SDK 版本为 3.50.1。如果你使用的 SDK 为之前版本,请查看以下变动,并进行相应适配。​
  • 3.60 版本中​
  • createRTCVideo 接口已变更为 createRTCEngine。​
  • publishScreen 和 unpublishScreen 接口已不存在。请使用 publishStreamVideo 和 publishStreamAudio 控制是否发布音视频。如果您已经调用 startScreenCapture,那么设置 publishStreamVideo(true) 将会直接开始发布屏幕流。​
  • 在屏幕准备好后,您会收到 onVideoDeviceStateChanged 回调。​
  • onUserUnPublishScreen 回调已不存在。请使用 onUserPublishStreamVideo 回调替代。使用 streamInfo.isScreen 来判断是否为屏幕流。​
  • 3.50.1 版本中​
  • 设置共享流的编码参数类型名称变更为 ScreenVideoEncoderConfig。​
  • 自定义屏幕流相关的接口名称和行为有变更。​
  • 3.43.1 版本中​
  • publishScreen 和 unpublishScreen 的类名由 RTCEngine 变更为 RTCRoom。其他方法的类名由 RTCEngine 变更为 RTCVideo。​
  • 回调类名由 IRTCEngineEventHandler 变更为 IRTCVideoEventHandler。​
  • 3.36.1 版本中​
  • 设置共享流的编码参数方法由 setVideoEncoderConfig 变更为 setScreenVideoEncoderConfig。​
  • publishScreen 等 API 的参数有变更。​
​
最近更新时间:2026.09.21 16:24:29
这个页面对您有帮助吗?
有用
有用
无用
无用