javascript - 使用 Electron 截取桌面截图

标签 javascript angular electron

我正在使用 Electron 创建一个创建全屏透明覆盖窗口的 Windows 应用程序。此覆盖的目的是:

  • 截取整个屏幕的屏幕截图(不是透明的覆盖层本身,而是屏幕“下方”),
  • 通过将图像作为字节流发送到我的 python 服务器和
  • 来处理此图像
  • 在叠加层上画一些东西

  • 我陷入了第一步,即屏幕截图捕获过程。
    我试过选项 1 ,即使用 capturePage() :
    this.electronService.remote.getCurrentWindow().webContents.capturePage()
        .then((img: Electron.NativeImage) => { ... }
    
    但这仅捕获了我的覆盖窗口(而不是桌面屏幕)。这将是一个空白图像,对我来说毫无用处。
    选项 2 是使用desktopCapturer :
    this.electronService.remote.desktopCapturer.getSources({types: ['screen']}).then(sources => {
        for (const source of sources) {
            if (source.name === 'Screen 1') {
                try {
                    const mediaDevices = navigator.mediaDevices as any;
                    mediaDevices.getUserMedia({
                        audio: false,
                        video: { // this specification is only available for Chrome -> Electron runs on Chromium browser
                            mandatory: {
                                chromeMediaSource: 'desktop',
                                chromeMediaSourceId: source.id,
                                minWidth: 1280,
                                maxWidth: 1280,
                                minHeight: 720,
                                maxHeight: 720
                            }
                        }
                    }).then((stream: MediaStream) => { // stream.getVideoTracks()[0] contains the video track I need
                        this.handleStream(stream);
                    });
                } catch (e) {
                }
            }
        }
    });
    
    下一步是它对我来说变得模糊的地方。收购的MediaStream怎么办?能从截图中得到一个字节流吗?我看到很多如何在网页上显示此流的示例,但我希望将其发送到我的后端。 This StackOverflow post提到如何做到这一点,但我没有让它正常工作。这就是我实现 handleStream() 的方式:
    import * as MediaStreamRecorder from 'msr';
    
    private handleStream(stream: MediaStream): void {
        recorder.stop()
        const recorder = new MediaStreamRecorder(stream);
        recorder.ondataavailable = (blob: Blob) => { // I immediately get a blob, while the linked SO page got an event and had to get a blob through event.data
            this.http.post<Result>('http://localhost:5050', blob);
        };
    
        // make data available event fire every one second
        recorder.start(1000);
    }
    
    blob Python服务器不接受。在检查 Blob 的内容后,这是我怀疑的视频。我用以下代码验证了这一点:
    let url = URL.createObjectURL(blob);
    window.open(url, '_blank')
    
    在新窗口中打开 blob。它显示可能半秒的视频,但我想要一个静态图像。那么如何从中获取特定的快照呢?我也不确定是否只需在 POST 正文中发送 Javascript blob 格式就可以让 Python 正确解释它。在 Java 中,它通过简单地发送 byte[] 来工作。图像,所以我验证了 Python 服务器实现按预期工作。
    除了使用 desktopCapturer 之外的任何建议也很好。这个实现也捕获了我的鼠标,我宁愿没有。我必须承认,我没想到这个功能会这么难实现。

    最佳答案

    以下是截取桌面屏幕截图的方法:

    const { desktopCapturer } = require('electron')
    
    document.getElementById('screenshot-button').addEventListener('click', () => { // The button which takes the screenshot
        desktopCapturer.getSources({ types: ['screen'] })
            .then( sources => {
                document.getElementById('screenshot-image').src = sources[0].thumbnail.toDataURL() // The image to display the screenshot
            })
    })
    
    使用“屏幕”将截取整个桌面的屏幕截图。
    使用“windows”将只截取应用程序的屏幕截图。
    另请参阅以下文档:https://www.electronjs.org/docs/api/desktop-capturer

    关于javascript - 使用 Electron 截取桌面截图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65750773/

    相关文章:

    javascript - VUE | JavaScript : How to access a key as a date format?

    arrays - 在 ngFor 中合并两个数组

    angular - 使用 Angular 7 在两个同级组件之间进行通信的方法,而无需为两者使用公共(public)服务

    javascript - 将动态菜单插入 Electron 菜单栏应用

    node.js - 关闭应用程序后,如何使其在后台运行?

    javascript - 使用箭头键移动对象的 Html 和 java 脚本?

    javascript - JavaScript 对象构造函数的问题,其中参数是其他对象

    angular - <mat-error> 从父组件中的自定义 formControl 继承验证时,在 ControlValueAccessor 中不起作用

    javascript - 如何在 Electron 应用程序中从协议(protocol)链接接收数据

    javascript - Jquery 更改未检测到选择更改 rails