基于webrtc浏览器截图

本文介绍了基于WebRTC实现在浏览器中截图并截取特定元素的方法。首先,利用navigator.mediaDevices.getDisplayMedia进行录屏,然后在video标签中播放并截取一帧。通过计算目标元素相对于浏览器的位置来精确截图。注意事项包括浏览器的安全策略限制,以及在非100%屏幕比例下可能存在的元素位置计算问题。示例代码展示了整个流程,并提供了测试按钮和展示截图的区域。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


需求简介

网页上某个元素截图,截图后需要显示

一、原理

浏览器提供的navigator.mediaDevices.getDisplayMedia方法可以实现录屏功能,我们将它投放到video标签中进行播放,然后截取其中的一帧。video标签放在最底层藏起来(display不能设none),计算目标元素的位置进行截图

二、实现

1.在页面中最底层放一个video标签,大小需要设置成屏幕的宽高。
2.计算浏览器位置,获取点击事件的鼠标在屏幕中的位置,在获取鼠标在浏览器中的位置,计算出浏览器在屏幕中的位置。这一步主要考虑浏览器未全屏。
3.计算元素在浏览器中的位置,递归获取元素与父元素的距离然后相加,注意需要处理浏览器的任务栏、菜单栏。
4.截图,将屏幕投入video中截取一帧后关闭投屏。
5.其他后续操作

测试代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
	</head>
	<body>
		<div style="width: 100%; height: 100%; position: relative; top: 0; left: 0; z-index: 1; overflow-y: hidden;">
			<video id="video" style="width: 1600; height: 900; position: absolute; top: 0; left: 0;" autoplay></video>
		</div>
		<div style="width: 100%; height: 100%; z-index: 2;">
			<button onclick="screenshoutBtnClick()">截图</button>
			<img id="showScreenShout" style="width: 320px; height: 200px;" />

			<div id="needScreenShotArea" style="width: 320px; height: 200px; background-color: aqua;">
				测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字
			</div>
		</div>
	</body>

	<script>
		function init() {
			if (window.screen) {
				var video = document.getElementById('video');
				video.style.width = window.screen.width + "px";
				video.style.height = window.screen.height + "px";
			}
		}

		init();

		const displayMediaOptions = {
			video: {
				cursor: "always"
			},
			audio: false
		};
		let videoElem = document.getElementById("video");

		function screenshoutBtnClick() {
			var windowX = event.screenX - event.clientX;
			var windowY = event.screenY - event.clientY;
			navigator.mediaDevices.getDisplayMedia(displayMediaOptions).then(stream => {
				videoElem.srcObject = stream;
				setTimeout(() => {
					var canvas = document.createElement("canvas");
					canvas.width = videoElem.clientWidth;
					canvas.height = videoElem.clientHeight;
					var needScreenShotEl = document.getElementById('needScreenShotArea');
					var pos = getPosition(needScreenShotEl);
					var toolBarHeight = window.outerHeight - window.innerHeight;
					canvas.getContext("2d").drawImage(videoElem, windowX + pos.left,
						windowY + (document.fullscreenElement ? pos.top : pos.top),
						needScreenShotEl.clientWidth, needScreenShotEl.clientHeight, 0, 0, canvas.width, canvas.height
					);
					var dataURL = canvas.toDataURL("image/png");
					document.getElementById('showScreenShout').src = dataURL;

					let tracks = videoElem.srcObject.getTracks();
					tracks.forEach(track => track.stop());
					videoElem.srcObject = null;
				}, 200)
			}).finally(() => {

			});
		}

		function getPosition(node) {
			//获取元素相对于其父元素的left值var left
			var left = node.offsetLeft;
			var top = node.offsetTop;
			// 取得元素的offsetParent
			current = node.offsetParent;

			// 一直循环直到根元素
			while (current != null) {
				left += current.offsetLeft;
				top += current.offsetTop;
				current = current.offsetParent;
			}
			return {
				"left": left,
				"top": top
			};
		}
	</script>
</html>

三、注意事项

1.浏览器安全策略

浏览器在https和localhost下才能无条件调用投屏,其它情况下需要设置白名单webrtc报错问题

2.元素位置计算

当前实现需要在屏幕100%显示下才能准确截取到目标元素,不是100%需要计算缩放

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值