Android如何实现两台手机屏幕共享和远程控制?最新 SDK 接入教程
笔者简介 长期关注 RTC 实时音视频领域的技术演进,参与过音视频算法工程化、接入实现与效果评估等相关工作。 在实际项目中,持续关注包括腾讯 TRTC、即构 ZEGO、 声网 Agora 在内的多家 RTC 厂商在实时通信能力与工程落地层面的实践,重点关注 SDK 接入、通话链路实现与场景化应用。系列文章将围绕 RTC SDK 接入与实时互动能力实现,持续输出工程实践与场景分析。 本文重点关注 Android 端音视频能力实现、屏幕共享与远程控制等典型场景。主要基于最新版本的 ZEGO SDK 接入文档整理,对部分接入流程和配置方式进行了更新。 屏幕共享,是指在视频通话或互动直播过程中将屏幕内容以视频的方式分享给其他的观众,以增强互动体验,提高沟通效率。 屏幕共享在如下场景中应用广泛: 请参考 下载示例源码 获取源码。 相关源码请查看 “/ZegoExpressExample/Others/src/main/java/im/zego/others/screensharing” 目录下的文件。 在实现屏幕共享功能之前,请确保: 下图展示了 Android 平台实现屏幕共享的数据流转: 在工程的 AndroidManifest.xml 文件中,增加屏幕录制的权限配置。设置完成后,在录制屏幕前,会弹窗提示用户是否允许应用录制屏幕,需要用户手动授权。 屏幕录制功能依赖于前台服务保活,进入您项目的 “app/src/main” 目录,打开 “AndroidManifest.xml” 文件,添加权限声明。 <!----> 如果目标 Android SDK 版本是 34.0.0 及以后版本,需要设置 注意 <!----> <!----> SDK 推流的“音频源”默认为麦克风,如果需要推屏幕共享源,需要通过 setAudioSource 切换为屏幕共享。 调用 startScreenCapture 接口共享整个系统的画面、采集第三方应用的音频。 开发者还可以使用 ZegoScreenCaptureConfig 参数设置是否采集视频、是否采集音频、设置音频采集时的采样率和采样通道等。 屏幕共享朝向支持跟随系统朝向和固定朝向,默认跟随系统朝向。可以设置 ZegoScreenCaptureConfig 中的 调用 updateScreenCaptureConfig 接口,可以更新屏幕共享的配置。 开发者需要监听 IZegoEventHandler 类中的以下回调: <!----> 调用 loginRoom 接口,传入房间 ID 参数 “roomID” 和用户参数 “user”,登录房间。 调用 startPublishingStream接口,传入流 ID 参数 “streamID”,向远端用户发送本端的音视频流。 至此,我们已完成采集屏幕数据并通过 ZEGO Express SDK 分享到远端的操作。 完成以上步骤之后,其他用户可以使用 startPlayingStream 接口拉取屏幕共享流。 用户可以调用 stopScreenCapture 接口停止共享。 如果你在接入过程中遇到问题,可以参考下方常见问题或官方文档进一步排查。 近期有项目规划,可以了解 RTC 产品报价,或点击官网右侧联系商务咨询折扣。 问题描述: 开启屏幕共享后,画面短暂显示后变黑,或频繁闪屏。 常见原因: 解决方案: 问题描述: 开启屏幕共享时,系统授权弹窗方向异常,甚至导致黑屏。 原因: 设备固定竖屏与 App 横屏界面冲突,引发系统数据异常。 解决方案: 问题描述: 共享画面正常,但对方听不到系统声音或应用声音。 常见原因: 解决方案: 问题描述: 共享画面卡顿、不流畅或延迟明显。 常见原因: 解决方案: 问题描述: 开启或停止屏幕共享时应用崩溃。 常见原因: 解决方案: 问题描述: 共享画面比例不对,出现拉伸或压缩。 常见原因: 解决方案: 问题描述: 调用屏幕共享时,没有出现系统授权弹窗。 常见原因: 解决方案: 问题描述: 切到后台后,屏幕共享自动停止。 常见原因: 解决方案: 问题描述: 不仅要共享屏幕,还需要远程控制另一台设备。 核心难点: 解决方案: 问题描述: 不同品牌手机(如小米、华为、OPPO)表现差异明显。 原因: 解决方案: 本文主要介绍了 Android 设备之间实现屏幕共享与远程控制的基础接入流程,结合实际开发中常见问题,对横竖屏适配、权限处理及稳定性问题进行了说明。通过这些能力,可以快速搭建远程协助、设备控制、内容共享等典型场景。 围绕屏幕共享与实时互动能力,我们还会持续整理更多细分场景与实现细节,包括但不限于: 本系列将围绕「RTC SDK 接入与实时互动能力实现」持续更新,适合需要构建屏幕共享、远程协作及实时互动能力的开发者参考。1 功能简介
2 屏幕共享示例源码下载
others
└── screensharing
└── ScreenSharingActivity.java
...
3 前提条件
4 实现流程
4.1(必选)获取用户录制屏幕授权
FOREGROUND_SERVICE 权限声明。<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
FOREGROUND_SERVICE 及 FOREGROUND_SERVICE_MEDIA_PROJECTION 权限声明。<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION"/>
<application>
<activity
android:name="im.zego.internal.screencapture.ZegoScreenCaptureManager$ZegoScreenCaptureAssistantActivity"
android:exported="false"
android:configChanges="screenSize|orientation"
android:screenOrientation="behind"
android:theme="@android:style/Theme.Translucent" />
<service
android:name="im.zego.internal.screencapture.ZegoScreenCaptureService"
android:enabled="true"
android:exported="false"
android:foregroundServiceType="mediaProjection">
<intent-filter>
<action android:name="android.intent.action.screenshare" />
</intent-filter>
</service>
</application>
4.2 设置采集源为屏幕共享源
engine.setVideoSource(ZegoVideoSourceType.SCREEN_CAPTURE, ZegoPublishChannel.MAIN);
engine.setAudioSource(ZegoAudioSourceType.SCREEN_CAPTURE, ZegoPublishChannel.MAIN);
4.3 开启屏幕共享
engine.startScreenCapture();
ZegoScreenCaptureConfig config = new ZegoScreenCaptureConfig();
config.captureVideo = true;
config.captureAudio = true;
config.audioParam.sampleRate = ZegoAudioSampleRate.ZEGO_AUDIO_SAMPLE_RATE_16K;
config.audioParam.channel = ZegoAudioChannel.STEREO;
// 可选参数,设置视频的采集区域,必须在原始的视频数据之内,单位为像素(px)
config.cropRect = new Rect(left, top, right, bottom);
engine.startScreenCapture(config);
4.3.1 设置屏幕共享朝向
orientation 参数来设置屏幕共享朝向。枚举值 说明 ZegoScreenCaptureOrientation.AUTO 跟随系统朝向,拉流端根据系统朝向展示画面 ZegoScreenCaptureOrientation.LANDSCAPE 固定横屏,拉流端始终横屏画面 ZegoScreenCaptureOrientation.PORTRAIT 固定竖屏,拉流端始终竖屏画面 ZegoScreenCaptureConfig config = new ZegoScreenCaptureConfig();
...
config.orientation = ZegoScreenCaptureOrientation.LANDSCAPE; // 固定横屏
engine.startScreenCapture(config);
4.4 更新屏幕共享配置
ZegoScreenCaptureConfig config = new ZegoScreenCaptureConfig();
config.captureVideo = true;
config.captureAudio = false;
config.audioParam.sampleRate = ZegoAudioSampleRate.ZEGO_AUDIO_SAMPLE_RATE_32K;
config.audioParam.channel = ZegoAudioChannel.STEREO;
config.orientation = ZegoScreenCaptureOrientation.PORTRAIT; // 固定竖屏
// 可选参数,设置视频的采集区域,必须在原始的视频数据之内,单位为像素(px)
config.cropRect = new Rect(left, top, right, bottom);
engine.updateScreenCaptureConfig(config);
4.5 监听屏幕共享回调通知
public void setEngineEventHandler(){
engine.setEventHandler(new IZegoEventHandler() {
@Override
public void onScreenCaptureExceptionOccurred(ZegoScreenCaptureExceptionType exceptionType) {
super.onScreenCaptureExceptionOccurred(exceptionType);
AppLogger.getInstance().receiveCallback("screen capture exception occurred: %s", exceptionType);
}
@Override
public void onScreenCaptureStart() {
super.onScreenCaptureStart();
AppLogger.getInstance().receiveCallback("screen capture start");
}
});
}
4.6 登录房间并开始推流
// 创建用户
ZegoUser user = new ZegoUser("user1");
// 开始登录房间
engine.loginRoom("room1", user);
// 开始推流
engine.startPublishingStream("stream1");
4.7 观看远端屏幕共享
// 拉流播放,需传入发起屏幕共享的用户推流时所用的 streamID
engine.startPlayingStream(streamID, new ZegoCanvas(playView));
4.8 停止屏幕共享
engine.stopScreenCapture();
5 获取屏幕共享 SDK 更多帮助
6 Android 屏幕共享常见问题(FAQ)
Android 屏幕共享时出现黑屏或闪屏,是什么原因?
MediaProjection 权限Android 设备固定竖屏时,屏幕共享弹窗方向异常怎么办?
screenOrientation 为 unspecifiedtools:replace 覆盖默认配置Android 屏幕共享为什么没有声音?
Android 屏幕共享画面卡顿或延迟高怎么办?
Android 屏幕共享时出现崩溃(Crash)如何排查?
Android 屏幕共享为什么分辨率异常或画面拉伸?
Android 屏幕共享权限弹窗无法弹出怎么办?
Android 屏幕共享在后台被中断怎么办?
Android 屏幕共享如何实现远程控制(反向操作)?
Android 屏幕共享在不同厂商设备上表现不一致怎么办?