Electron UI BrowserWindow冻结主浏览器窗口

时间:2016-12-19 13:06:05

标签: javascript node.js multithreading screenshot electron

代码参考https://github.com/aredfox/screencapturer

问题描述Here是一个electron应用,其中包含" MainWindow"按住按钮"开始捕获"。点击后,它会向主进程发出一个事件,然后主进程启动一个新的,单独的," BrowserWindow"被称为“捕捉窗口”的对象'与它自己的capture.html和capture.js相关联。在capture.js中,每三秒钟制作一个屏幕截图并保存到c:\ temp \ screencap(这是一个演示应用程序来说明问题,因此我现在没有使这个可配置和硬编码路径)。每次在'craptureWindow'中进行捕捉。它冻结了,我期待它。但是,' mainWindow'对象冻结了,我没想到它会这样做。 我应该如何处理这个问题,以便当一个进程在另一个" BrowserWindow"中运行时,mainWindow不会冻结。宾语?我假设电子BrowserWindows(或"标签")有一个单独的线程?

编辑2016年12月12日 可能的罪魁祸首是desktopCapturer.getSources()。

ADDENDUM:发现问题必须在getMainSource的代码块内,因为当我缓存那个" source"结果它不会冻结整个电子。因此,必须是过滤方法或获取屏幕本身导致冻结问题。

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(又名" source")的结果,因为它每次都会产生相同的图像数据。我通过将文件写为png来验证,然后每个屏幕截图都是完全相同的,即使桌面上有足够的更改。 TODO:可能的选项是设置视频流并从流中保存图像?

1 个答案:

答案 0 :(得分:0)

如果你想跨平台捕捉截图,我建议使用下面的方法,而不是依赖内置的电子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);
            }
        });
    }
}
/*/********************************************************************///