electron录制工具-desktopCapturer录屏

需求

录屏状态时,屏幕底部有个计时器,点击计时器停止录屏,跳转录屏结束的视频播放。

效果如下

electron-录屏演示

实现

计时器

创建一个浮窗,根据x、y坐标移动窗口的位置;

复制代码
	// 获取屏幕的主显示器信息
	const { width, height } = screen.getPrimaryDisplay().workAreaSize;

	// 设置窗口的宽度和高度
	const windowWidth = 120;
	const windowHeight = 120;
	// app.commandLine.appendSwitch('disable-features', 'IOSurfaceCapturer,DesktopCaptureMacV2')
	recordWin = new BrowserWindow({
		width: windowWidth,
		height: windowHeight,
		x: width / 2 - windowWidth / 2,
		y: height - windowHeight,
		frame: true, // 无边框
		transparent: true, // 透明窗口
		alwaysOnTop: true, // 窗口总是显示在最前面
		webPreferences: {
			preload: path.join(__dirname, 'preload.mjs'),
		},
	})

为了时间准确,使用时间戳计算录屏时长。

复制代码
const updateDuration = () => {
			if (!recordRef.current.status) return
			setDuration(formatSecondsToHMS((new Date().getTime() - recordRef.current.startTime) / 1000))
			requestAnimationFrame(updateDuration)
		}

录屏

electron提供了desktopCapturer 共享屏幕接口,渲染进程通过 navigator.mediaDevices.getUserMedia 与 MediaRecorder 结合获取录制屏幕的blob

复制代码
// main.js
		desktopCapturer.getSources({ types: ['screen'] }).then(() => {
			recordWin?.webContents.send('start_record_main', 'screen:1:0')
			// 可以选择不同的窗口
			// for (const source of sources) {
			// 	if (source.name === 'Electron') {
			// 		maskWin?.webContents.send('SET_SOURCE', source.id)
			// 		return
			// 	}
			// }
		})

// render.js

const mediaStream = await navigator.mediaDevices.getUserMedia({
					audio: false,
					video: {
						mandatory: {
							chromeMediaSource: 'desktop',
							chromeMediaSourceId: sourceId,
						}
					}
				})
			
				const options = { mimeType: 'video/webm; codecs=vp9' }; 
				const mediaRecorder = new MediaRecorder(mediaStream, options);

				mediaRecorder.onstart = () => {
						recordRef.current.recordedChunks = [];
						recordRef.current.status = true
						updateDuration()
				}
				mediaRecorder.ondataavailable = function (event) {
						if (event.data.size > 0) {
							recordRef.current.recordedChunks.push(event.data);
						}
				};
		
				mediaRecorder.onstop = async () => {
						const blob = new Blob(recordRef.current.recordedChunks, { type: 'video/webm' });
						const url = URL.createObjectURL(blob);
						// downloadVideo(url);
						recordRef.current.recordedChunks = [];
						recordRef.current.status = false
						window.ipcRenderer.send('stop_record_render', url)
				};
				mediaRecorder.onerror = (event) => {
					console.error("MediaRecorder error:", event);
				};
				mediaRecorder.start();

跳转视频编辑页面

复制代码
	window.ipcRenderer.send('stop_record_render', url)

注:录屏也可以使用ffmpeg

代码

相关推荐
IT_陈寒1 小时前
Java中equals方法比了个寂寞?原来这才是正确的重写姿势
前端·人工智能·后端
默_笙1 小时前
🚓 分诊台与拆题术:让 RAG 学会判断和规划
前端·javascript
CopyCode1 小时前
用 AI 迁项目有多爽?我把 Webpack 迁 Vite 的全过程记下来了
前端·架构
去伪存真1 小时前
Electron 自动化发布指南:GitHub Actions 跨平台打包全纪录
前端·electron
计算机魔术师1 小时前
OpenAI智能体失控闯进美国政府网站,53张用户图片外泄背后
前端
颜进强1 小时前
14 · NestJS ExecutionContext 执行上下文:守卫、拦截器、过滤器拿到的"同一个 context",为什么能力不一样?
前端·后端·ai编程
程序员Flycan1 小时前
🚀 跨域终结者:前端代理服务器(Proxy)原理解析与配置总结
前端
怕浪猫1 小时前
顶级模型一句话,AI 写出了能玩的 QQ飞车
前端·面试·github
huakoh1 小时前
MCP 报错分不清?先看响应里是 result 还是 error
前端
呃呃呃呃ex1 小时前
10. 现代前端工程化:ES6 React 项目实战与原理解析
前端·javascript