JavaScript的媒体设备API为屏幕捕获提供了原生支持,开发者无需依赖第三方插件,就能在浏览器环境中获取屏幕的实时媒体流,进而实现各类和屏幕内容相关的功能。屏幕捕获得到的媒体流和普通摄像头流类似,都遵循媒体流的标准规范,可以进行后续的处理和分发。

屏幕捕获的核心API
实现屏幕捕获最核心的方法是MediaDevices.getDisplayMedia(),它是浏览器提供的用于获取屏幕、窗口或浏览器标签页的媒体流的方法,属于WebRTC规范的一部分,目前主流现代浏览器都已经支持该API。
和获取摄像头流的getUserMedia不同,getDisplayMedia的调用会触发浏览器的屏幕选择弹窗,用户需要手动选择要捕获的屏幕区域,这是出于隐私保护的强制要求,开发者无法绕过这个交互步骤。
getDisplayMedia的基本使用
该方法接收一个约束对象作为参数,用来指定捕获的媒体类型和参数,比如是否需要音频、视频的分辨率等,调用后返回一个Promise,成功时返回媒体流对象。
// 请求屏幕捕获权限并获取媒体流
async function captureScreen() {
try {
// 约束配置:需要视频流,不需要音频
const constraints = {
video: {
cursor: "always" // 显示鼠标光标
},
audio: false
};
// 调用getDisplayMedia获取屏幕流
const screenStream = await navigator.mediaDevices.getDisplayMedia(constraints);
console.log("成功获取屏幕媒体流", screenStream);
return screenStream;
} catch (error) {
// 用户拒绝授权或捕获失败时的处理
console.error("屏幕捕获失败:", error);
return null;
}
}
媒体流的常见处理场景
获取到屏幕媒体流之后,我们可以基于流对象实现多种功能,以下是几个典型的使用场景。
在页面中播放屏幕流
最直接的使用方式是将媒体流绑定到<video>元素上,实现屏幕内容的实时预览,只需要将流的引用赋值给video元素的srcObject属性即可。
// 将屏幕流绑定到video元素播放
async function playScreenStream() {
const videoElement = document.getElementById("screen-video");
const stream = await captureScreen();
if (stream) {
// 将媒体流赋值给video的srcObject
videoElement.srcObject = stream;
// 监听视频播放结束(用户停止共享屏幕)
videoElement.onended = () => {
console.log("用户停止了屏幕共享");
// 停止所有流的轨道
stream.getTracks().forEach(track => track.stop());
};
}
}
对应的HTML结构如下:
<video id="screen-video" autoplay playsinline controls></video> <button onclick="playScreenStream()">开始捕获屏幕</button>
录制屏幕流
结合MediaRecorder API,我们可以对获取到的屏幕流进行录制,生成视频文件供用户下载。MediaRecorder可以接收媒体流作为输入,将流数据编码为指定的视频格式。
// 录制屏幕流并生成视频文件
let mediaRecorder = null;
let recordedChunks = [];
async function startRecordScreen() {
const stream = await captureScreen();
if (!stream) return;
// 创建MediaRecorder实例,指定录制格式
mediaRecorder = new MediaRecorder(stream, {
mimeType: "video/webm;codecs=vp9"
});
// 收集录制的数据块
mediaRecorder.ondataavailable = (event) => {
if (event.data.size > 0) {
recordedChunks.push(event.data);
}
};
// 录制结束时生成文件
mediaRecorder.onstop = () => {
const blob = new Blob(recordedChunks, { type: "video/webm" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "screen-record.webm";
a.click();
// 释放URL对象
URL.revokeObjectURL(url);
recordedChunks = [];
};
// 开始录制
mediaRecorder.start();
console.log("开始录制屏幕");
}
function stopRecordScreen() {
if (mediaRecorder && mediaRecorder.state !== "inactive") {
mediaRecorder.stop();
console.log("停止录制屏幕");
}
}
注意事项与兼容性问题
- 隐私限制:
getDisplayMedia必须在安全上下文环境中调用,也就是页面需要使用HTTPS协议,或者是在localhost、127.0.0.1等本地环境下才能正常工作,HTTP协议的线上环境无法使用该API。 - 用户交互要求:该API的调用最好绑定在用户的点击等交互事件中,部分浏览器不允许在非用户交互触发的逻辑中调用该API,否则会直接抛出错误。
- 流的生命周期管理:当屏幕共享结束时,需要手动调用流中所有轨道的
stop方法释放资源,避免占用系统资源导致后续捕获失败。 - 浏览器兼容性:虽然主流浏览器都支持该API,但部分旧版本浏览器可能存在兼容性问题,使用前可以通过
navigator.mediaDevices && typeof navigator.mediaDevices.getDisplayMedia === "function"来判断是否支持。
常见问题解答
捕获屏幕时为什么没有声音
默认情况下getDisplayMedia的音频捕获是关闭的,如果需要捕获系统声音,需要将约束中的audio设置为true,同时用户在选择共享屏幕时需要勾选共享系统音频的选项,部分浏览器可能不支持系统音频捕获,需要做好降级处理。
如何只捕获某个窗口而不是整个屏幕
捕获的范围是用户在选择弹窗中手动选择的,开发者无法在代码中指定具体捕获哪个窗口,只能通过在约束中配置相关参数,比如video: { displaySurface: "window" }来建议浏览器优先展示窗口选项,但最终选择权仍在用户手中。
屏幕捕获功能涉及用户隐私,开发中需要明确告知用户捕获的用途,并且仅在必要的时候请求相关权限,避免引起用户的隐私担忧。
JavaScript屏幕捕获媒体流MediaDevicesgetDisplayMedia修改时间:2026-07-23 02:27:33