截图与视频
截图与视频
截图
最简单的截图就是直接使用
desktopCapturer.getSources(
{
types: ["screen"],
thumbnailSize: {
width: width * scaleFactor,
height: height * scaleFactor
}
},
(error, sources) => {
console.timeEnd("capture");
let imgSrc = sources[0].thumbnail.toDataURL();
let capture = new CaptureRenderer($canvas, $bg, imgSrc, scaleFactor);
}
);
替代的方法是可以使用
const handleStream = stream => {
document.body.style.cursor = oldCursor;
document.body.style.opacity = "1";
// Create hidden video tag
let video = document.createElement("video");
video.style.cssText = "position:absolute;top:-10000px;left:-10000px;";
// Event connected to stream
let loaded = false;
video.onloadedmetadata = () => {
if (loaded) {
return;
}
loaded = true;
// Set video ORIGINAL height (screenshot)
video.style.height = video.videoHeight + "px"; // videoHeight
video.style.width = video.videoWidth + "px"; // videoWidth
// Create canvas
let canvas = document.createElement("canvas");
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
let ctx = canvas.getContext("2d");
// Draw video on canvas
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
if (this.callback) {
// Save screenshot to png - base64
this.callback(canvas.toDataURL("image/png"));
} else {
// console.log('Need callback!')
}
// Remove hidden video tag
video.remove();
try {
stream.getTracks()[0].stop();
} catch (e) {
// nothing
}
};
video.srcObject = stream;
document.body.appendChild(video);
};
// mac 和 windows 获取 chromeMediaSourceId 的方式不同
if (require("os").platform() === "win32") {
require("electron").desktopCapturer.getSources(
{
types: ["screen"],
thumbnailSize: { width: 1, height: 1 }
},
(e, sources) => {
let selectSource = sources.filter(
source => source.display_id + "" === curScreen.id + ""
)[0];
navigator.getUserMedia(
{
audio: false,
video: {
mandatory: {
chromeMediaSource: "desktop",
chromeMediaSourceId: selectSource.id + "",
minWidth: 1280,
minHeight: 720,
maxWidth: 8000,
maxHeight: 8000
}
}
},
handleStream,
handleError
);
}
);
} else {
navigator.getUserMedia(
{
audio: false,
video: {
mandatory: {
chromeMediaSource: "desktop",
chromeMediaSourceId: `screen:${curScreen.id}`,
minWidth: 1280,
minHeight: 720,
maxWidth: 8000,
maxHeight: 8000
}
}
},
handleStream,
handleError
);
}
多屏幕支持
由于全屏情况,窗口只能占据一个屏幕,所以多屏截图只能用多个截屏窗口来处理了。
const captureScreen = (e, args) => {
if (captureWins.length) {
return;
}
const { screen } = require("electron");
let displays = screen.getAllDisplays();
// 循环创建截屏窗口
captureWins = displays.map(display => {
let captureWin = new BrowserWindow({
// window 使用 fullscreen, mac 设置为 undefined, 不可为 false
fullscreen: os.platform() === "win32" || undefined,
width: display.bounds.width,
height: display.bounds.height,
x: display.bounds.x,
y: display.bounds.y,
transparent: true,
frame: false,
movable: false,
resizable: false,
enableLargerThanScreen: true,
hasShadow: false
});
captureWin.setAlwaysOnTop(true, "screen-saver");
captureWin.setFullScreenable(false);
captureWin.loadFile(path.join(__dirname, "capture.html"));
// 调试用
// captureWin.openDevTools()
// 一个窗口关闭则关闭所有窗口
captureWin.on("closed", () => {
let index = captureWins.indexOf(captureWin);
if (index !== -1) {
captureWins.splice(index, 1);
}
captureWins.forEach(win => win.close());
});
return captureWin;
});
};
然后每个窗口截取当前屏幕的画面进行操作,获取当前屏幕可以下面的方法:
// 因为窗口是全屏的, 所以可以直接用 x, y 来对比
const getCurrentScreen = () => {
let { x, y } = currentWindow.getBounds();
return screen
.getAllDisplays()
.filter(d => d.bounds.x === x && d.bounds.y === y)[0];
};
MAC 下截取全屏窗口
let captureWin = new BrowserWindow({
// window 使用 fullscreen, mac 设置为 undefined, 不可为 false
fullscreen: os.platform() === "win32" || undefined,
width: display.bounds.width,
height: display.bounds.height,
x: display.bounds.x,
y: display.bounds.y,
transparent: true,
frame: false,
movable: false,
resizable: false,
enableLargerThanScreen: true,
hasShadow: false,
show: false
});
// 黑魔法...
app.dock.hide();
captureWin.setAlwaysOnTop(true, "screen-saver");
captureWin.setVisibleOnAllWorkspaces(true);
captureWin.setFullScreenable(false);
captureWin.show();
app.dock.show();
captureWin.setVisibleOnAllWorkspaces(false);