本次介绍的截屏功能一共有两种分别是在electron环境中与非electron环境中
非electron环境
这个环境下会有一些限制:
1.只能截浏览器中的画面
2.如果里面有iframe或者base64的图片会加载不出来(这个会有解决办法)
yarn add -D js-web-screen-shot
使用的话也非常简单,直接上代码了
javascript
<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模式,但是也不是所有的浏览器都支持,很操但
javascript
new ScreenShot ({
enableWebRtc: true, // 改成true
clickCutFullScreen: true,
level: 9999, //层级级别
completeCallback: callback
})
electron环境
electron环境下之前的方法可以使用,但是弊端也有,不过可以从electron中获取当前应用的视频流信息,可以规避这个问题
第一步就是从主线程中调用desktopCapturer获取当前应用的ID
javascript
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获取视频流
javascript
// 获取指定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);
});
});
}
然后把视频流直接怼到这个截屏组件上
javascript
getInitStream(id: string).then(res=> {
new ScreenShot ({
enableWebRtc: true,
creenFlow: res1!, // 传入屏幕流数据
clickCutFullScreen: true,
level: 9999, //层级级别
completeCallback: callback
})
})
如果你只是想要截浏览器内的内容,这个就满足你的需求了!
但是如果你想做成跟微信QQ一样能截应用外面的,就要使用第三方库
这里就直接使用QQ封装好的截图工具(非常好用)
javascript
exec(path.join(__dirname, '..', '..', 'static', 'PrintScr.exe'))
稍后遗憾的是,人家封装好的有别人的业务功能(转发功能)
如果不想用人家封装好的话就需要自己调用dll文件去做一遍,不过在electron中调用dll, 那就得安装ffi ,那是非常难安依赖。
就这样吧 资源在这了自己去拉吧