uni-app app端屏幕共享必须依赖原生插件(如trtc/zego sdk)调用系统api(android mediaprojection/ios replaykit),因webview不支持getdisplaymedia,纯h5方案必然失败。

uni-app 实现 App 端实时屏幕共享,核心不是靠 H5 的 getDisplayMedia(它在 iOS/Android WebView 中基本不可用),而是必须走原生能力封装 + WebRTC 媒体管道注入。不接入原生插件或 SDK,纯前端代码在 App 环境下无法拿到系统级屏幕流。
为什么 navigator.mediaDevices.getDisplayMedia 在 App 里大概率失败
uni-app 打包成 App 后运行在 WebView 容器中(iOS 是 WKWebView,Android 多为系统 WebView 或 X5),而 getDisplayMedia 在这些环境中:iOS 完全不支持;Android 大部分版本返回 NotFoundError 或直接静默拒绝。即使某些定制内核支持,也缺乏权限弹窗、窗口层级控制、后台共享等关键能力。
- 错误现象常见:
DOMException: getDisplayMedia not supported或NotAllowedError: Permission denied - 真机调试时 Chrome DevTools 无法捕获屏幕流,不代表逻辑错——是底层根本没暴露该 API
- 不要尝试用
canvas.captureStream()模拟:帧率低、CPU 占用高、无法捕获其他应用画面,仅适用于页面内局部录制
必须用 TRTC / ZEGO / Agora 等音视频 SDK 的 screenCapture 接口
主流方案都提供 startScreenCapture 这类原生方法,由插件桥接调用系统录屏 API(Android 的 MediaProjection,iOS 的 ReplayKit)。uni-app 项目需引入对应 SDK 的 uni-app 插件(如 @tencentcloud/trtc-unipackage 或官方维护的 zego-express-engine-unipackage)。
- 调用前必须申请对应平台权限:Android 需动态申请
android.permission.FOREGROUND_SERVICE+ 录屏弹窗授权;iOS 需在Info.plist加NSMicrophoneUsageDescription和NSCameraUsageDescription(即使只共享屏幕,部分 SDK 仍会校验) - 编码参数直接影响体验:
videoResolution建议设为TRTCVideoResolution_1280_720,videoFps控制在 8–10,videoBitrate1500–2000 kbps;过高会导致低端机发热卡顿 - 务必区分主流(摄像头)和辅流(屏幕):
startScreenCapture第二个参数通常要传TRTCVideoStreamType.TRTCVideoStreamTypeSub,否则会覆盖本地摄像头画面
接收端不能只靠 onUserVideoAvailable 监听
Android/iOS 用户开启屏幕共享后,远端用户收到 onUserVideoAvailable 回调,但此时只是“通知有辅流”,真正渲染还需手动调用 startRemoteView 并指定流类型。漏掉这步,画面永远黑屏。
- 典型错误写法:监听到事件后直接调用
startRemoteView(userId, viewRef),没传第 3 个参数streamType - 正确做法:
startRemoteView(userId, viewRef, TRTCVideoStreamType.TRTCVideoStreamTypeSub) - 注意生命周期:页面退到后台时,需调用
stopRemoteView,否则可能引发内存泄漏或下次进房拉流失败 - Android 上若使用
TextureView渲染,需确保其宽高比与编码分辨率一致,否则拉伸/裁剪异常
信令与状态同步必须自己补全
SDK 只管媒体流传输,不负责“谁在共享”“共享是否结束”这类业务状态。你需要用 WebSocket 或 TUIRoomKit 的信令通道,主动广播和监听自定义事件。
- 例如:A 开始共享时,发一条
{ type: 'screen_share_start', userId: 'A', streamId: 'sub_123' }到房间信令通道;B 收到后才触发startRemoteView - 不能依赖 SDK 自动触发 UI 更新——TUIRoomKit 的底部按钮点击只调
startScreenCapture,但不会帮你推信令 - 用户切后台、杀进程、网络断开时,需在
onUserOffline或心跳超时后主动清理本地渲染视图,否则残留黑块
最易被忽略的一点:iOS 屏幕共享必须在前台激活状态下启动,且首次调用 startScreenCapture 会触发系统级录屏权限弹窗;这个弹窗无法预判是否被用户拒绝,必须监听 SDK 的失败回调(如 onScreenCaptureStarted 不触发、或回调 error code 为 ERR_SCREEN_CAPTURE_PERMISSION_DENIED),并引导用户去系统设置手动开启。











