文章目录
quick-start
// index.js
const { app, BrowserWindow } = require('electron');
app.on('ready', function() {
console.log('ready');
const mainWin = new BrowserWindow({
width: 800,
height: 600
});
mainWin.loadFile('index.html');
})
主进程和渲染进程
electron
运行 package.json
main
脚本的进程被称为主进程, 在主进程中运行的脚本通过创建 web 页面来展示用户界面。
主进程运行在 nodejs 环境中
主进程和渲染进程的区别
主进程使用BrowserWindow
实例创建页面, 每个BrowserWindow
实例在自己的渲染进程里运行页面, 当一个BrowserWindow
实例被销毁后, 对应的渲染进程也会被终止。
主进程管理所有的 web 页面和他们的渲染进程。 每个渲染进程是独立的, 它只关心它运行的 web 页面。
在页面中调用与GUI
相关的原生API
是不被允许的, 因为在 web
页面里操作原生GUI
资源非常危险, 容易造成资源泄漏。如果想在 web
页面里使用 GUI
操作, 其对应的渲染进程必须与主进程进行通讯, 请求主进程进行相关操作。
app 模块
ready 应用程序初始化完成
browser-ready-created 窗口创建完成触发
before-quit 窗口关闭之前
will-quit 窗口关闭, 但程序没有关闭, 即将关闭
quit 应用程序关闭触发
whenReady() then()
requestSingleInstanceLock() 限制只打开一个应用程序 true 或者 false
second-instance事件
BrowserWindow 模块
用于创建控制应用程序窗口
app.on('ready', function() {
console.log('ready');
const mainWin = new BrowserWindow({
width: 800,
height: 600,
// frame: false,
// maxWidth: 1000,
// maxHeight: 800,
// minWidth: 800,
// minHeight: 600,
show: false,
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
});
mainWin.loadURL('http://www.baidu.com');
// mainWin.setBounds({
// x: 500,
// y: 500
// })
mainWin.once('ready-to-show', function() {
mainWin.show();
})
mainWin.on('show', function() {
mainWin.maximize();
})
})
loadFile 方法
用于加载本地文件, 可以使用相对路径, 也可以使用绝对路径。
可以加载非项目中的文件。
不止可以加载 html
文件, 也可以加载其他文件
loadURL 方法
用于加载远程文件
frame 配置
设置窗口是否带有边框和菜单栏, 默认是 true
resizeable 配置
设置窗口是否可以改变大小, 默认是 true
maxWidth, maxHeight, minWidth, minHeight
设置最大宽度、最大高度、最小宽度、最小高度
show 配置
设置窗口是否显示, 默认为 true
ready-to-show 事件
渲染进程首次渲染页面触发该事件, 仅触发一次
与 show 配置结合使用:
const mainWin = new BrowserWindow({
show: false
});
mainWin.once('ready-to-show', function() {
mainWin.show();
})
show 方法, 控制窗口的显示
webReference 配置
配置项是一个对象
- nodeIntegration
是否开启 node 支持, 默认 false
- contextIsolation
是否开启上下文隔离, 默认 true
setBounds 方法
设置窗口大小或移动位置
maximize 方法
设置窗口最大化
进程通信
主进程使用 ipcMain
ipcMain.on('renderer-send', (event, data) => {
console.log(data);
event.reply('main-send', '主进程回复消息')
})
渲染进程使用 ipcRenderer
const {
ipcRenderer
} = require('electron');
document.querySelector('button').addEventListener('click', function(e) {
ipcRenderer.send('renderer-send', '渲染进程传递的信息');
})
ipcRenderer.on('main-send', (event, data) => {
console.log(data);
})
系统托盘
Tray: 添加图标和上下文菜单到系统通知区
进程: 主进程
const tray = new Tray('icon.jpg');
// 设置展示文字
tray.setToolTip('wcy录屏');
Menu
Menu: 创建原生应用菜单和上下文菜单
进程: 主进程
const tray = new Tray('icon.jpg');
tray.setToolTip('wcy录屏');
const menu = Menu.buildFromTemplate([{
label: '退出',
click: () => {
console.log('点击退出')
}
}])
屏幕分享和摄像头拍摄
MediaDevices
WebRtc
MediaDevices
接口提供访问连接媒体输入的设备, 如照相机和麦克风, 以及屏幕共享等, 它可以使你取得任何硬件资源的媒体数据
- getUserMedia
在用用户允许情况下, 打开系统上的相机或屏幕共享和麦克风, 并提供MediaStream
包含视频轨道和音频轨道的输入
<video src=""></video>
<script>
const video = document.querySelector('video');
const init = async() => {
const stream = await navigator.mediaDevices.getUserMedia({
video: {
width: 600,
height: 500
}
});
video.srcObject = stream;
video.play();
};
init();
</script>
- getDisplayMedia
提示用户选择显示器或显示器的一部分以捕获MediaStream
以便共享或记录, 返回解析为MediaStream
的 Promise
<video src=""></video>
<script>
const video = document.querySelector('video');
const init = async() => {
const stream = await navigator.mediaDevices.getDisplayMedia({
video: true
});
video.srcObject = stream;
video.play();
};
init();
</script>
原生屏幕录制
MediaRecorder
<body>
<p>Media</p>
<button class="start">开始录制</button>
<button class="end">停止录制</button>
<button class="play">播放</button>
<video src="" class="video"></video>
<video src="" class="playVideo"></video>
<script>
const video = document.querySelector('.video');
const playVideo = document.querySelector('.playVideo');
const startBtn = document.querySelector('.start');
const endBtn = document.querySelector('.end');
const playBtn = document.querySelector('.play');
let stream = null;
let record = null;
let data = [];
const init = async() => {
stream = await navigator.mediaDevices.getUserMedia({
video: {
width: 600,
height: 500
}
});
video.srcObject = stream;
video.play();
};
init();
const startRedord = startRecord = () => {
console.log(stream);
record = new MediaRecorder(stream, {
mimeType: 'video/webm'
});
if (record) {
record.start();
record.addEventListener('dataavailable', function(e) {
data.push(e.data);
});
// record.addEventListener('stop', function(e) {
// console.log(data);
// })
}
};
startBtn.addEventListener('click', function(e) {
startRedord();
});
endBtn.addEventListener('click', function(e) {
record.stop();
});
playBtn.addEventListener('click', function(e) {
const blob = new Blob(data, {
type: 'video/mp4'
});
const videoUrl = URL.createObjectURL(blob);
console.log(videoUrl);
playVideo.src = videoUrl;
playVideo.play();
});
</script>
</body>