在网页端实现屏幕录制功能,主要是借助浏览器提供的原生Web API或者成熟的第三方库来完成,不同的技术方案适配不同的业务场景,下面详细介绍4种常见的实现方式。

方案一:MediaStream API + MediaRecorder 基础录制
这是最基础的网页录屏实现方案,核心是通过getDisplayMedia方法获取屏幕媒体流,再用MediaRecorder对媒体流进行录制,适合只需要录制整个屏幕内容的简单场景。
实现步骤
- 调用
navigator.mediaDevices.getDisplayMedia获取屏幕媒体流,该方法会弹出浏览器自带的屏幕选择弹窗,用户可以选择要录制的屏幕、窗口或浏览器标签页 - 创建
MediaRecorder实例,传入获取到的媒体流,同时可以配置录制格式、码率等参数 - 监听
MediaRecorder的dataavailable事件收集录制数据,监听stop事件将收集到的数据生成可播放的视频文件 - 通过
start和stop方法控制录制的开始和结束
代码示例
let mediaRecorder = null;
let recordedChunks = [];
// 开始录制
async function startRecord() {
try {
// 获取屏幕媒体流
const stream = await navigator.mediaDevices.getDisplayMedia({
video: {
cursor: 'always' // 显示鼠标光标
},
audio: false // 不录制音频,如需录制可配置为true
});
// 创建MediaRecorder实例
mediaRecorder = new MediaRecorder(stream, {
mimeType: 'video/webm;codecs=vp9' // 指定录制格式
});
// 收集录制数据
mediaRecorder.ondataavailable = (e) => {
if (e.data.size > 0) {
recordedChunks.push(e.data);
}
};
// 录制结束处理
mediaRecorder.onstop = () => {
// 生成视频Blob
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.revokeObjectURL(url);
recordedChunks = [];
// 停止屏幕流的所有轨道
stream.getTracks().forEach(track => track.stop());
};
// 开始录制,每1000ms收集一次数据
mediaRecorder.start(1000);
} catch (err) {
console.error('录制失败:', err);
}
}
// 停止录制
function stopRecord() {
if (mediaRecorder && mediaRecorder.state !== 'inactive') {
mediaRecorder.stop();
}
}
方案二:Canvas captureStream 自定义绘制录制
如果需要在录制过程中对画面进行自定义处理,比如添加水印、绘制标注、合并多个画面,可以使用Canvas的captureStream方法获取Canvas的媒体流,再结合MediaRecorder进行录制,适合需要自定义画面内容的场景。
实现逻辑
首先将需要录制的内容绘制到Canvas上,然后调用Canvas的captureStream方法获取媒体流,后续流程和方案一类似,用MediaRecorder处理该媒体流即可。如果需要录制页面原有内容,可以先用html2canvas等库将页面内容绘制到Canvas,或者直接在Canvas上绘制动态内容。
代码示例
let canvasMediaRecorder = null;
let canvasRecordedChunks = [];
let canvasStream = null;
// 开始Canvas录制
function startCanvasRecord() {
const canvas = document.getElementById('recordCanvas');
// 获取Canvas媒体流,参数表示帧率
canvasStream = canvas.captureStream(30);
canvasMediaRecorder = new MediaRecorder(canvasStream, {
mimeType: 'video/webm'
});
canvasMediaRecorder.ondataavailable = (e) => {
if (e.data.size > 0) {
canvasRecordedChunks.push(e.data);
}
};
canvasMediaRecorder.onstop = () => {
const blob = new Blob(canvasRecordedChunks, {
type: 'video/webm'
});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'canvas_record.webm';
a.click();
URL.revokeObjectURL(url);
canvasRecordedChunks = [];
canvasStream.getTracks().forEach(track => track.stop());
};
canvasMediaRecorder.start(1000);
// 模拟在Canvas上绘制动态内容
drawCanvasContent(canvas);
}
// 模拟Canvas绘制内容
function drawCanvasContent(canvas) {
const ctx = canvas.getContext('2d');
let x = 0;
const timer = setInterval(() => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#f0f0f0';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = 'red';
ctx.fillRect(x, 50, 50, 50);
x += 2;
if (x > canvas.width) {
clearInterval(timer);
}
}, 30);
// 停止录制时清除定时器
canvasMediaRecorder.onstop = () => {
clearInterval(timer);
const blob = new Blob(canvasRecordedChunks, {
type: 'video/webm'
});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'canvas_record.webm';
a.click();
URL.revokeObjectURL(url);
canvasRecordedChunks = [];
canvasStream.getTracks().forEach(track => track.stop());
};
}
// 停止Canvas录制
function stopCanvasRecord() {
if (canvasMediaRecorder && canvasMediaRecorder.state !== 'inactive') {
canvasMediaRecorder.stop();
}
}
方案三:WebRTC 远程流录制
如果录制的屏幕内容需要实时传输到远端服务器,或者需要和其他用户共享录制内容,可以结合WebRTC技术,将屏幕媒体流通过WebRTC传输,在接收端或者传输过程中进行录制,适合远程协作、在线教学等场景。
实现思路
首先通过getDisplayMedia获取屏幕流,然后将该流添加到WebRTC的RTCPeerConnection中,通过信令服务器和远端建立连接,将屏幕流传输到远端。远端收到流之后,可以用MediaRecorder对接收到的流进行录制,也可以将流结合其他内容处理后录制。
核心代码示例
let peerConnection = null;
let webrtcRecordedChunks = [];
let webrtcMediaRecorder = null;
// 初始化WebRTC连接并开始录制
async function startWebRTCRecord() {
// 获取屏幕流
const screenStream = await navigator.mediaDevices.getDisplayMedia({
video: true,
audio: false
});
// 创建RTCPeerConnection
peerConnection = new RTCPeerConnection({
iceServers: [
{ urls: 'stun:stun.ipipp.com:3478' }
]
});
// 将屏幕流添加到连接中
screenStream.getTracks().forEach(track => {
peerConnection.addTrack(track, screenStream);
});
// 模拟接收到远端流(实际场景通过信令交换SDP和ICE候选)
peerConnection.ontrack = (e) => {
const remoteStream = e.streams[0];
// 对远端接收到的屏幕流进行录制
webrtcMediaRecorder = new MediaRecorder(remoteStream, {
mimeType: 'video/webm'
});
webrtcMediaRecorder.ondataavailable = (event) => {
if (event.data.size > 0) {
webrtcRecordedChunks.push(event.data);
}
};
webrtcMediaRecorder.onstop = () => {
const blob = new Blob(webrtcRecordedChunks, {
type: 'video/webm'
});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'webrtc_record.webm';
a.click();
URL.revokeObjectURL(url);
webrtcRecordedChunks = [];
};
webrtcMediaRecorder.start(1000);
};
// 创建Offer
const offer = await peerConnection.createOffer();
await peerConnection.setLocalDescription(offer);
// 实际场景需要将Offer发送到信令服务器,这里省略信令交换流程
}
// 停止WebRTC录制
function stopWebRTCRecord() {
if (webrtcMediaRecorder && webrtcMediaRecorder.state !== 'inactive') {
webrtcMediaRecorder.stop();
}
if (peerConnection) {
peerConnection.close();
peerConnection = null;
}
}
方案四:第三方库封装方案
如果不想处理底层API的兼容性和复杂逻辑,可以使用成熟的第三方库来简化实现,常见的库有recordrtc、screen-recorder等,这些库封装了不同浏览器的兼容性处理,提供了更简洁的API,适合快速开发场景。
以recordrtc为例的实现
首先需要引入recordrtc库,然后调用其提供的API即可快速实现屏幕录制,不需要手动处理MediaRecorder的数据收集和格式适配。
代码示例
let recordRTC = null;
// 开始录制
async function startWithRecordRTC() {
const screenStream = await navigator.mediaDevices.getDisplayMedia({
video: true,
audio: true
});
// 创建RecordRTC实例
recordRTC = RecordRTC(screenStream, {
type: 'video',
mimeType: 'video/webm',
bitsPerSecond: 1280000 // 设置码率
});
recordRTC.startRecording();
}
// 停止录制并下载
function stopWithRecordRTC() {
if (recordRTC) {
recordRTC.stopRecording(() => {
const blob = recordRTC.getBlob();
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'recordrtc_screen.webm';
a.click();
URL.revokeObjectURL(url);
recordRTC.destroy();
recordRTC = null;
});
}
}
不同方案对比
下面从适用场景、开发难度、兼容性三个方面对4种方案进行对比,方便开发者选择:
| 方案 | 适用场景 | 开发难度 | 兼容性 |
|---|---|---|---|
| MediaStream + MediaRecorder | 简单屏幕录制,不需要自定义画面 | 低 | 主流现代浏览器支持 |
| Canvas captureStream | 需要自定义绘制、添加水印、合并画面 | 中 | 支持captureStream的浏览器可用 |
| WebRTC远程流录制 | 远程协作、实时共享录制内容 | 高 | 需要浏览器支持WebRTC和屏幕捕获 |
| 第三方库方案 | 快速开发,不需要处理兼容细节 | 极低 | 依赖库的兼容处理 |
注意事项
- 浏览器兼容性:
getDisplayMedia和MediaRecorder在部分旧版本浏览器上不支持,使用前可以做特性检测 - 用户权限:屏幕录制需要用户手动授权,用户拒绝授权时接口会抛出错误,需要做异常处理
- 资源释放:录制结束后要及时停止媒体流的所有轨道,释放摄像头、屏幕捕获等资源,避免资源占用
- 录制格式:不同浏览器支持的
mimeType不同,可以先检测浏览器支持的格式再设置参数,避免录制失败
MediaStream_APIMediaRecorderCanvas_captureStreamWebRTC修改时间:2026-07-19 19:12:19