开放 Web 上的 WebRTC 实时音视频是标配能力——直到它跑在 WebView 里。Android 把 getUserMedia 的权限决策推给宿主,iOS WKWebView 默认关闭媒体采集。多数内置浏览器根本连不上通话。宿主自有 runtime 桥接实时媒体——统一的摄像头、麦克风与点对点连接 API。

Android:权限决策在宿主手里

当页面调用 navigator.mediaDevices.getUserMedia 时,WebView 不会向用户弹窗,而是调用 WebChromeClient.onPermissionRequest,由宿主决定授权与否。在 grant 之前,宿主必须先请求 Android 运行时权限 CAMERA 与 RECORD_AUDIO,最好再校验来源 origin。若这条链没接上,日志会出现 CheckMediaAccessPermission: Not supported,getUserMedia 静默 reject 为 NotAllowedError。Android 官方文档写得很明确:调用 grant() 前必须先请求 Android 运行时权限。所以实时通话能否连上,完全取决于容器是否实现了这条桥。

iOS:媒体采集默认关闭

iOS 11 把 WebRTC 带到了 Safari,但 WKWebView 默认不启用媒体采集。第三方 App 必须显式配置:在 Info.plist 加 NSCameraUsageDescription 与 NSMicrophoneUsageDescription,设置 allowsInlineMediaPlayback = true 与 mediaTypesRequiringUserActionForPlayback = [],iOS 14+ 还需通过 WKMediaCapturePermissionsPolicy 显式允许。即便如此,微信、抖音、Facebook 等内置浏览器常常不启用,于是 getUserMedia 报 not found。更进一步,声网 Web SDK 指出:iOS Safari 与 WKWebView 不支持 getDisplayMedia(屏幕共享);App 切到后台时 AVCaptureSession 不允许使用摄像头,远端看到黑屏;通过 RTCRTPSender.setParameters 指定帧率也不可用。

通话失声时,什么会崩

  • 视频客服与远程医疗卡住。 通话始终拿不到摄像头。
  • 语聊房与直播连麦静音。 麦克风流到不了对端。
  • 屏幕共享不可用。 iOS WebView 不支持 getDisplayMedia。
  • 切后台就断线。 App 进后台时摄像头黑屏。
  • Safari 能连 ≠ WebView 能连。 同一台设备的 Safari 能连,内置浏览器却失败。

runtime 解法

宿主自有 runtime 桥接实时媒体层。它用原生摄像头与麦克风权限包裹 getUserMedia,并对外暴露统一的摄像头、麦克风与点对点连接 API。宿主维护稳定的 RTCPeerConnection——共享的 STUN/TURN、ICE 处理,以及硬件编解码(H.264/VP8)协商——让实时通话在每种引擎、每个内置浏览器上都能连。权限原生请求一次;流与连接保持一致。

维度WebView宿主自有 runtime
Android 权限宿主 onPermissionRequest原生授权
iOS 采集默认关闭原生开启
屏幕共享getDisplayMedia 不支持原生桥
后台摄像头黑屏宿主托管会话
点对点连接因引擎而异统一
一致性因引擎而异统一

原生 App 能在每台手机上跑视频通话,裸 WebView 几乎一台都跑不了。runtime 给页面一个媒体面——另一端是一个活的对端。

参考来源