Mac Catalyst下Electron应用WebRTC屏幕共享报错解决方案咨询
一、修复Electron desktopCapturer的Cannot read property 'srcObject' of undefined错误
这个错误几乎都是因为DOM元素未初始化就赋值,或者preload上下文无法直接访问渲染进程DOM导致的,按以下步骤修复:
用IPC隔离preload和渲染进程的DOM操作
在preload.js中通过contextBridge暴露安全API,避免直接操作DOM:// preload.js const { contextBridge, ipcRenderer } = require('electron'); contextBridge.exposeInMainWorld('screenCaptureAPI', { requestCapture: () => ipcRenderer.invoke('trigger-screen-capture'), onStreamReady: (callback) => ipcRenderer.on('stream-ready', (_, stream) => callback(stream)) });主进程中处理屏幕捕获请求
// main.js const { app, BrowserWindow, ipcMain, desktopCapturer } = require('electron'); ipcMain.handle('trigger-screen-capture', async (event) => { // 获取屏幕/窗口源 const sources = await desktopCapturer.getSources({ types: ['screen', 'window'] }); if (sources.length === 0) return; // 捕获屏幕流 const stream = await navigator.mediaDevices.getUserMedia({ video: { mandatory: { chromeMediaSource: 'desktop', chromeMediaSourceId: sources[0].id, minWidth: 1280, maxWidth: 1920, minHeight: 720, maxHeight: 1080 } } }); // 发送流到渲染进程 event.sender.send('stream-ready', stream); });渲染进程中等待DOM就绪后接收流
// renderer.js 或前端页面脚本 document.addEventListener('DOMContentLoaded', async () => { const screenVideo = document.getElementById('screen-video'); await window.screenCaptureAPI.requestCapture(); window.screenCaptureAPI.onStreamReady((stream) => { screenVideo.srcObject = stream; }); });额外注意:升级Electron版本到20.x以上,旧版本对Mac Catalyst的desktopCapturer支持存在兼容性问题。
二、解决navigator.mediaDevices.getDisplayMedia不支持问题
虽然Mac Catalyst原生支持该API,但Electron的Chromium内核默认可能未启用,按以下配置尝试:
添加Chromium启动参数
在主进程app就绪前添加启动开关:// main.js app.commandLine.appendSwitch('enable-features', 'WebRTCDisplayMediaWithDesktopCapture'); app.commandLine.appendSwitch('enable-usermedia-screen-capturing');配置屏幕录制权限
- 打包应用时,需要在entitlements文件中添加屏幕录制权限:
<!-- entitlements.plist --> <key>com.apple.security.device.audio-input</key> <true/> <key>com.apple.security.device.camera</key> <true/> <key>com.apple.security.screen-capture</key> <true/> - 安装应用后,前往Mac系统设置→安全性与隐私→屏幕录制,勾选你的应用。
- 打包应用时,需要在entitlements文件中添加屏幕录制权限:
如果仍不生效,说明Electron对Mac Catalyst的getDisplayMedia支持存在bug,建议切换到Electron beta版本或等待官方修复。
三、替代WebRTC屏幕共享方案(若上述方法失效)
如果Mac Catalyst环境下Web API和desktopCapturer都无法正常工作,可以尝试以下方案:
方案1:基于Electron原生屏幕捕获+WebRTC流转发
用desktopCapturer捕获流后,直接将该MediaStream传入你现有WebRTC通话的addTrack方法,整合到音视频流中发送,无需额外转换。方案2:Mac原生AVFoundation捕获屏幕
编写Objective-C/Swift原生模块,用AVCaptureSession捕获屏幕帧,将帧数据转换为Electron可传递的格式,再通过IPC发送到渲染进程转换为MediaStream,最终接入WebRTC。这种方式兼容性最好,但需要原生开发能力。方案3:libwebrtc直接调用
基于libwebrtc的原生API实现屏幕捕获,绕过Electron的Chromium层限制,但复杂度较高,适合对WebRTC底层有了解的开发者。
内容的提问来源于stack exchange,提问作者Smit Rathod

