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.getUserMediaMediaRecorder 结合获取录制屏幕的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

代码

相关推荐
子兮曰6 分钟前
深入 HTML-in-Canvas:当 Canvas 学会了渲染 DOM,前端图形生态要变天了
前端·javascript·canvas
ws_qy13 分钟前
从大模型原理到前端 AI Coding 工程化实践
前端·ai编程
倾颜33 分钟前
React 19 源码主线拆解 04:Fiber 到底是什么,React 为什么需要 Fiber?
前端·react.js·源码阅读
AI攻城狮38 分钟前
国产大模型能力大比拼,社区有话说
前端
IT_陈寒1 小时前
Vite的public文件夹放静态资源?这坑我替你踩了
前端·人工智能·后端
涵涵(互关)1 小时前
GoView各项目文件中的相关语法2
前端·javascript·vue.js
子兮曰2 小时前
别让爬虫白嫖你的导航站了:纯免费,手把手实现加密字体防爬
前端·javascript·后端
小村儿2 小时前
连载06 - Hooks 源码深度解析:Claude Code 的确定性自动化体系
前端·后端·ai编程
心中无石马2 小时前
uniapp引入tailwindcss4.x
前端·css·uni-app
焰火19992 小时前
[Vue]可重置的响应式状态reactive
前端·vue.js