• 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

    代码

  • 相关阅读:
    [附源码]计算机毕业设计JAVAjsp小微企业库存管理系统
    Revit 平面的圆弧,空间的椭圆弧
    Nexus私服(三)
    数智化重塑冷链物流行业,SaaS云系统开发方案赋能冷链企业实现高效运营
    接口测试项目(非常值得练手)
    【luogu P3249】【LOJ 2052】矿区(对偶图)(dfs)
    vscode | 开发神器vscode快捷键删除和恢复
    套餐内商品的排列顺序(字符串的排列),剑指offer,力扣
    魔改xxl-job,彻底告别手动配置任务!
    【js】单文件上传和大文件分片上传功能实现
  • 原文地址:https://blog.csdn.net/weixin_42429220/article/details/139580199