javascript - Electron UI BrowserWindow 卡住主 BrowserWindow

标签 javascript node.js multithreading screenshot electron

代码引用 : https://github.com/aredfox/screencapturer

问题描述 :
Hereelectron带有“MainWindow”的应用程序,其中包含一个“开始捕获”按钮。一旦单击它会向主进程触发一个事件,然后主进程会启动一个新的、单独的“BrowserWindow”对象,称为“captureWindow”,它自己的 capture.html 和 capture.js 相关联。在 capture.js 中,每三秒制作一次屏幕截图并将其保存到 c:\temp\screencap(这是一个演示应用程序来说明问题,因此我暂时没有对其进行配置和硬编码路径)。每次在“craptureWindow”中进行捕获时,它都会卡住,这是我所期望的。但是,“mainWindow”对象也卡住了,这是我没想到的。 我应该如何处理这个问题,以便在另一个“BrowserWindow”对象中运行进程时主窗口不会卡住?我假设 Electron BrowserWindows(或“标签”)有一个单独的线程?

编辑 20/12/2016
可能的罪魁祸首是 desktopCapturer.getSources()。

附录:发现问题必须在getMainSource的代码块内,因为当我缓存该“源”结果时,它不会卡住整个 Electron 。因此,一定是过滤方法或获取屏幕本身导致了卡住问题。

function getMainSource(desktopCapturer, screen, done) {
    const options = {
        types: ['screen'], thumbnailSize: screen.getPrimaryDisplay().workAreaSize
    }
    desktopCapturer.getSources(options, (err, sources) => {
        if (err) return console.log('Cannot capture screen: ', err)

        const isMainSource = source => source.name === 'Entire screen' || source.name === 'Screen 1'
        done(sources.filter(isMainSource)[0])
    })
}

解决方案虽然不是缓存 getMainSource(又名“源”)的结果,因为它每次都会产生相同的图像数据。我通过以 png 格式写入文件来验证这一点,实际上每个屏幕截图都是完全相同的,即使桌面上已经发生了足够多的变化。 待办事项:可能的选择是设置视频流并从流中保存图像?

最佳答案

如果您想跨平台捕获屏幕截图,我建议您使用以下方法,而不是依赖内置的 Electron API。并不是说它们不好,但它们不适合例如每三秒截屏一次。

我的解决方案是 npm-module desktop-screenshot - 和一个名为 hazardous 的 npm 包,因为这是 Windows 和 asar 执行所需要的。

我最终实现的代码是这样的——它可能是您问题的灵感来源/示例。

/* ******************************************************************** */
/* MODULE IMPORTS */
import { remote, nativeImage } from 'electron';
import path from 'path';
import os from 'os';
import { exec } from 'child_process';
import moment from 'moment';
import screenshot from 'desktop-screenshot';
/* */
/*/********************************************************************///

/* ******************************************************************** */
/* CLASS */
export default class ScreenshotTaker {    
    constructor() {
        this.name = "ScreenshotTaker";        
    }

    start(cb) {
        const fileName = `cap_${moment().format('YYYYMMDD_HHmmss')}.png`;
        const destFolder = global.config.app('capture.screenshots');
        const outputPath = path.join(destFolder, fileName);        
        const platform = os.platform();
        if(platform === 'win32') {
            this.performWindowsCapture(cb, outputPath);
        }
        if(platform === 'darwin') {
            this.performMacOSCapture(cb, outputPath);
        }
        if(platform === 'linux') {
            this.performLinuxCapture(cb, outputPath);
        }
    }

    performLinuxCapture(cb, outputPath) {
        // debian
        exec(`import -window root "${outputPath}"`, (error, stdout, stderr) => {
            if(error) {
                cb(error, null, outputPath);
            } else {
                cb(null, stdout, outputPath);
            }
        });
    }
    performMacOSCapture(cb, outputPath) {
        this.performWindowsCapture(cb, outputPath);
    }
    performWindowsCapture(cb, outputPath) {
        require('hazardous');
        screenshot(outputPath, (err, complete) => {
            if(err) {
                cb(err, null, outputPath);
            } else {
                cb(null, complete, outputPath);
            }
        });
    }
}
/*/********************************************************************///

关于javascript - Electron UI BrowserWindow 卡住主 BrowserWindow,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41223268/

相关文章:

c# - 什么是非线程安全?

javascript - 图像 slider 在 javascript/HTML 中不起作用

java - LinkedBlockingQueue 的插入和删除方法是线程安全的吗?

javascript - HTML 表格的 JSON 格式

node.js - nightwatch.js 入门

node.js - 使用 ExclusiveStartKey 选项的 AWS Dynamodb 扫描

javascript - 强制将 heroku/Angular 应用程序重定向到 HTTPS 版本

java - 是否可以并行检查方法调用所花费的时间

javascript - Jest 中的嵌套模拟函数

JavaScript:一个简单的 'compare' 函数不起作用?