Ссылка на код : https://github.com/aredfox/screencapturer
Описание проблемы : Вот electronic с" MainWindow ", в котором есть кнопка" Начать захват ". После щелчка по нему запускается событие для основного процесса, затем основной процесс запускает новый, отдельный объект «BrowserWindow», называемый «captureWindow», с собственными связанными файлами capture.html и capture.js. В capture.js каждые три секунды делается снимок экрана и сохраняется в c: \ temp \ screencap (это демонстрационное приложение для иллюстрации проблемы, поэтому я пока не делал это настраиваемым и жестко закодировал путь). Каждый раз, когда в craptureWindow делается захват, он зависает, как я и ожидал. Но объект mainWindow также зависает, чего я не ожидал. Как мне с этим справиться, чтобы mainWindow не зависала, когда процесс выполняется в другом объекте BrowserWindow? Я предположил, что в электронном браузере Windows (или "вкладках") есть отдельный поток?
РЕДАКТИРОВАТЬ 20/12/2016 Возможный виновник - desktopCapturer.getSources ().
ДОБАВЛЕНИЕ: обнаружено, что проблема должна быть внутри кодового блока getMainSource
, потому что, когда я кэширую этот "исходный" результат, он не замораживает весь электрон. Таким образом, должно быть, что метод фильтрации или получение самого экрана вызывает проблему зависания.
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, и действительно, каждый снимок экрана был таким же, хотя на рабочем столе было достаточно изменений. ЗАДАЧИ: Возможный вариант - настроить видеопоток и сохранить изображение из потока?
1 ответ
Если вы хотите делать скриншоты кросс-платформенных, я бы посоветовал использовать описанный ниже подход вместо того, чтобы полагаться на встроенный электронный API. Не то чтобы они плохие, но они не подходят, например, для создания снимков экрана каждые три секунды.
Решением для меня был npm-модуль desktop-screenshot и пакет 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
По вопросам программирования на ECMAScript (JavaScript/JS) и его различных диалектах/реализациях (кроме ActionScript). Обратите внимание, что JavaScript — это НЕ Java. Включите все теги, относящиеся к вашему вопросу: например, [node.js], [jQuery], [JSON], [ReactJS], [angular], [ember.js], [vue.js], [typescript], [стройный] и т. д.