渲染网站时使用电子捕获屏幕

问题描述 投票:0回答:2

我有一个电子应用程序,可以在互联网上加载网页。 该网站的主要功能之一是捕获屏幕的能力,它使用

navigator.mediaDevices.getDisplayMedia({video: true});

但显然,电子将通过权限被拒绝,因为不会弹出“选择捕获窗口”来授予它任何权限。

我已经查看了一些文章并看到了desktopCapture

问题是,这种情况正在发生并通过网页 javascript 运行,而不是我的应用程序的代码,所以我不知道如何影响它。

那么在这种情况下我应该怎么做才能捕获屏幕呢?

electron screen-capture
2个回答
5
投票

您可以重写

navigator.mediaDevices.getDisplayMedia
来调用 Electron 的
desktopCapturer
API,如下所示。此实现假设您已启用
contextIsolation
,这是 Electron >= 12

中的默认行为
// preload.js

const { desktopCapturer, contextBridge } = require("electron");
const { readFileSync } = require("fs");
const { join } = require("path");

// inject renderer.js into the web page
window.addEventListener("DOMContentLoaded", () => {
  const rendererScript = document.createElement("script");
  rendererScript.text = readFileSync(join(__dirname, "renderer.js"), "utf8");
  document.body.appendChild(rendererScript);
});

contextBridge.exposeInMainWorld("myCustomGetDisplayMedia", async () => {
  const sources = await desktopCapturer.getSources({
    types: ["window", "screen"],
  });

  // you should create some kind of UI to prompt the user
  // to select the correct source like Google Chrome does
  const selectedSource = sources[0]; // this is just for testing purposes

  return selectedSource;
});

// renderer.js

navigator.mediaDevices.getDisplayMedia = async () => {
  const selectedSource = await globalThis.myCustomGetDisplayMedia();

  // create MediaStream
  const stream = await navigator.mediaDevices.getUserMedia({
    audio: false,
    video: {
      mandatory: {
        chromeMediaSource: "desktop",
        chromeMediaSourceId: selectedSource.id,
        minWidth: 1280,
        maxWidth: 1280,
        minHeight: 720,
        maxHeight: 720,
      },
    },
  });

  return stream;
};

现在,当调用此 API 时,将按预期返回一个流给调用者

navigator.mediaDevices.getDisplayMedia({video: true});

我创建了一个 GitHub 存储库,其中包含此解决方案的有效实现


0
投票

Electron desktopCapturer 有实现屏幕共享的完整说明。

只需在 main.js 中添加此代码

app.whenReady().then(() => {
const mainWindow = new BrowserWindow()
session.defaultSession.setDisplayMediaRequestHandler((request, callback) => {
desktopCapturer.getSources({ types: ['screen'] }).then((sources) => {
  // Grant access to the first screen found.
  callback({ video: sources[0], audio: 'loopback' })
  })
})  
  mainWindow.loadFile('index.html')
})
© www.soinside.com 2019 - 2024. All rights reserved.