Electron+Vue实现截屏功能的两种方式

Electron+Vue实现截屏功能的两种方式

本次介绍的截屏功能一共有两种分别是在electron环境中与非electron环境中

非electron环境

这个环境下会有一些限制:

1.只能截浏览器中的画面

2.如果里面有iframe或者base64的图片会加载不出来(这个会有解决办法)

yarn add -D js-web-screen-shot

使用的话也非常简单,直接上代码了

template div class="screenWrapper" h1 这里是截屏界面 /h1 button id="startButton" class="button" @click='showVideo' 开始截屏 /button div class="imgWrapepr" img :src='srcData' width="200px"/ /div /div /template script setup lang="ts" import { ref } from 'vue'import ScreenShot from "js-web-screen-shot";const srcData = ref()const videoRef = ref()const showVideo = () = { new ScreenShot ({ enableWebRtc: false, clickCutFullScreen: true, level: 9999, //层级级别 completeCallback: callbackSrc })}const callbackSrc = (data: any) = { srcData.value = data.base64} /script style lang="less" scoped .screenWrapper { -webkit-app-region: no-drag; background-color: white; height: 100vh; width: 100vw; padding: 20px; h1 { color: green; } .imgWrapepr { border: 1px solid #ccc; width: 500px; height: 500px; }}.box-img{ width: 200px; position: fixed; right: 10px; top: 10px; border: 2px solid red; } /style

但是会有第二种的限制,如果画面有iframe 的话就不行了,就像这样

这种情况下就得开启webrtc模式,但是也不是所有的浏览器都支持,很操但

new ScreenShot ({ enableWebRtc: true, // 改成true clickCutFullScreen: true, level: 9999, //层级级别 completeCallback: callback })

electron环境

electron环境下之前的方法可以使用,但是弊端也有,不过可以从electron中获取当前应用的视频流信息,可以规避这个问题

第一步就是从主线程中调用desktopCapturer获取当前应用的ID

const selfWindws = async () = await Promise.all( webContents .getAllWebContents() .filter((item) = { const win = BrowserWindow.fromWebContents(item); return win win.isVisible(); }) .map(async (item) = { const win = BrowserWindow.fromWebContents(item); const thumbnail = await win?.capturePage(); // 当程序窗口打开DevTool的时候 也会计入 return { name: win?.getTitle() + (item.devToolsWebContents === null ? "" : "-dev"), // 给dev窗口加上后缀 id: win?.getMediaSourceId(), display_id: "", appIcon: null, }; }) );

拿到ID之后用js获取视频流

// 获取指定id设备的视频流export const getInitStream = async ( source: { id: string }, audio?: boolean): Promise MediaStream | null = { return new Promise((resolve, _reject) = { // 获取指定窗口的媒体流 // 此处遵循的是webRTC的接口类型 暂时TS类型没有支持 只能断言成any (navigator.mediaDevices as any) .getUserMedia({ audio: audio ? { mandatory: { chromeMediaSource: "desktop", }, } : false, video: { mandatory: { chromeMediaSource: "desktop", chromeMediaSourceId: source.id, }, }, }) .then((stream: MediaStream) = { resolve(stream); }) .catch((error: any) = { console.log(error); resolve(null); }); });}

然后把视频流直接怼到这个截屏组件上

getInitStream(id: string).then(res= { new ScreenShot ({ enableWebRtc: true, creenFlow: res1!, // 传入屏幕流数据 clickCutFullScreen: true, level: 9999, //层级级别 completeCallback: callback })})

如果你只是想要截浏览器内的内容,这个就满足你的需求了!

但是如果你想做成跟微信QQ一样能截应用外面的,就要使用第三方库

这里就直接使用QQ封装好的截图工具(非常好用)

exec(path.join(__dirname, '..', '..', 'static', 'PrintScr.exe'))

稍后遗憾的是,人家封装好的有别人的业务功能(转发功能)

如果不想用人家封装好的话就需要自己调用dll文件去做一遍,不过在electron中调用dll, 那就得安装ffi ,那是非常难安依赖。

就这样吧 资源在这了自己去拉吧

https://github.com/liangtongzhuo/electron_screenshot.git

Electron+Vue实现截屏功能的两种方式