You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Electron中Webview加载Google Meet无法共享屏幕的解决方案咨询

在Electron Webview中实现Google Meet屏幕共享的解决方案

问题描述

我正在开发一个运行Google Meet Webview的Electron应用,其余功能均正常,但尝试屏幕共享时会提示“browser does not support share screen”错误。有人建议使用Electron的desktopCapturer模块,但我不清楚如何在Webview中使用该模块。

现有代码

main.js

const { app, BrowserWindow, desktopCapturer } = require('electron')
    
let mainWindow
    
function createWindow() {
    mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            nodeIntegration: true,
            webviewTag: true
        }
    })

    mainWindow.loadFile('index.html')

    mainWindow.on('closed', function () {
        mainWindow = null
    })

    mainWindow.webContents.on('did-finish-load', function() {
      
    })
}

app.on('ready', createWindow)

app.on('window-all-closed', function () {
    if (process.platform !== 'darwin') {
        app.quit()
    }
})

app.on('activate', function () {
    if (mainWindow === null) {
        createWindow()
    }
})

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <webview
      autosize="on"
      src="https://meet.google.com/"
      id="webview"
      data-home="https://meet.google.com/"
      style="width: 100%; height: 100vh;"
    ></webview>
</body>
</html>

解决方案

Electron Webview默认不支持原生屏幕共享API,需通过desktopCapturer配合IPC通信实现,核心逻辑是让主进程获取屏幕源,再传递给Webview页面替换Google Meet的共享请求。

步骤1:修改Webview配置

更新index.html中的Webview标签,添加权限和预加载脚本(预加载脚本用于隔离环境下的IPC通信):

<webview
  autosize="on"
  src="https://meet.google.com/"
  id="webview"
  data-home="https://meet.google.com/"
  style="width: 100%; height: 100vh;"
  webpreferences="preload=./preload.js, contextIsolation=true"
  allowpopups
  media="audio,video"
></webview>

步骤2:创建预加载脚本preload.js

该脚本负责拦截Google Meet的屏幕共享请求,通过IPC向主进程获取屏幕源并返回媒体流:

const { ipcRenderer } = require('electron');

// 替换原生的getDisplayMedia方法
Object.defineProperty(navigator.mediaDevices, 'getDisplayMedia', {
  value: async () => {
    // 向主进程请求屏幕/窗口源
    const sources = await ipcRenderer.invoke('get-desktop-sources');
    
    // 示例:直接返回第一个屏幕源的媒体流(可扩展为弹窗让用户选择)
    const stream = await navigator.mediaDevices.getUserMedia({
      audio: false,
      video: {
        mandatory: {
          chromeMediaSource: 'desktop',
          chromeMediaSourceId: sources[0].id,
          minWidth: 1280,
          maxWidth: 1920,
          minHeight: 720,
          maxHeight: 1080
        }
      }
    });
    return stream;
  }
});

步骤3:更新主进程main.js

添加IPC监听逻辑,调用desktopCapturer获取屏幕源并返回给Webview:

const { app, BrowserWindow, desktopCapturer, ipcMain } = require('electron')
    
let mainWindow
    
function createWindow() {
    mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            nodeIntegration: false, // 关闭nodeIntegration,启用上下文隔离提升安全性
            contextIsolation: true,
            webviewTag: true
        }
    })

    mainWindow.loadFile('index.html')

    mainWindow.on('closed', function () {
        mainWindow = null
    })
}

// 处理Webview的屏幕源请求
ipcMain.handle('get-desktop-sources', async () => {
  const sources = await desktopCapturer.getSources({
    types: ['window', 'screen'],
    thumbnailSize: { width: 1280, height: 720 }
  });
  return sources;
})

app.on('ready', createWindow)

app.on('window-all-closed', function () {
    if (process.platform !== 'darwin') {
        app.quit()
    }
})

app.on('activate', function () {
    if (mainWindow === null) {
        createWindow()
    }
})

关键说明

  • 启用contextIsolation并关闭nodeIntegration是Electron安全最佳实践,避免Webview内的外部页面访问主进程API。
  • 若需要让用户自主选择共享的屏幕/窗口,可在预加载脚本中创建弹窗UI,展示所有sources的缩略图,用户选择后再返回对应ID的媒体流。

内容的提问来源于stack exchange,提问作者Question hunter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 16:07:47