为什么使用 MediaRecorder API 录屏
现代浏览器提供了 MediaRecorder API,它配合 navigator.mediaDevices 可以捕获屏幕或摄像头视频流,并生成可下载视频文件,无需插件、支持主流格式如 video/webm(部分浏览器支持 video/mp4),适合前端实现录屏功能。
获取屏幕与音频流
录屏的核心是使用 navigator.mediaDevices.getDisplayMedia() 请求屏幕捕获权限,例如整个屏幕、应用窗口或特定浏览器标签页。你还可以通过 navigator.mediaDevices.getUserMedia() 获取麦克风或摄像头音频流,然后合并多个流:
const screenStream = await navigator.mediaDevices.getDisplayMedia({ video: { cursor: 'always' } });
const audioStream = await navigator.mediaDevices.getUserMedia({ audio: true, video: false });
const combined = new MediaStream([...screenStream.getTracks(), ...audioStream.getTracks()]);
这样即可录制带音频的屏幕画面。
设置 MediaRecorder 并控制录制流程
使用合并后的 MediaStream 创建 MediaRecorder 实例,可选设置 mimeType 和比特率:
const recorder = new MediaRecorder(combined, { mimeType: 'video/webm;codecs=vp9' });
let chunks = [];
recorder.ondataavailable = evt => { if (evt.data.size > 0) chunks.push(evt.data); };
recorder.onstop = () => {
const blob = new Blob(chunks, { type: chunks[0].type });
const url = URL.createObjectURL(blob);
// 在视频元素中播放或提供下载链接
};
recorder.start(200);
start(200) 表示每隔 200 ms 切分数据块,这样可以更灵活地处理录制内容。
停止录制与资源释放
当用户点击“停止录制”按钮时,需要调用:
recorder.stop();
combined.getTracks().forEach(track => track.stop());
停止录制并关闭所有媒体轨道,释放系统资源、停止权限占用,确保不会一直占用摄像头、麦克风或屏幕流。
示意完整 UI 与代码逻辑
下面是一个基本的 HTML + JavaScript 示例结构:
<button id="start-btn">开始录屏</button>
<button id="stop-btn" disabled>停止录屏</button>
<video id="preview" controls></video>
<script>
const startBtn = document.getElementById('start-btn');
const stopBtn = document.getElementById('stop-btn');
const preview = document.getElementById('preview');
let recorder, chunks = [];
startBtn.onclick = async () => {
const screen = await navigator.mediaDevices.getDisplayMedia({ video: true });
const audio = await navigator.mediaDevices.getUserMedia({ audio: true });
const stream = new MediaStream([...screen.getTracks(), ...audio.getTracks()]);
recorder = new MediaRecorder(stream);
recorder.ondataavailable = e => { if (e.data.size > 0) chunks.push(e.data); };
recorder.onstop = () => {
const blob = new Blob(chunks, { type: 'video/webm' });
preview.src = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = preview.src;
a.download = 'screen-record.webm';
a.textContent = '下载视频';
document.body.appendChild(a);
};
recorder.start();
startBtn.disabled = true;
stopBtn.disabled = false;
};
stopBtn.onclick = () => {
recorder.stop();
recorder.stream.getTracks().forEach(t => t.stop());
startBtn.disabled = false;
stopBtn.disabled = true;
};
</script>
兼容性与格式支持建议
大多数现代浏览器支持 getDisplayMedia() 和 MediaRecorder; 不过 video/mp4 的支持仍受限于浏览器,建议默认使用 video/webm。部分 Safari/Firefox 在本地开发可直接使用 mp4,但上线项目需谨慎检测支持性。
推荐使用静态方法 MediaRecorder.isTypeSupported() 检查格式支持,并在不支持时 fallback 到默认格式。
进阶功能建议
- 暂停与恢复录制:可通过 recorder.pause() 和 recorder.resume() 暂停与恢复录制流程。
- 合并摄像头画面:可将摄像头视频以画中画(PIP)形式整合到屏幕录制流中,提升互动性。
- 上传服务端:将录制后的 Blob 上传,用于远程存储、处理或分析。
- UI 提示优化:提示用户录制状态、剩余时间、错误捕获等信息提升体验。
总结
使用 JavaScript 的 MediaRecorder API 与 getDisplayMedia(),你可以在网页中轻松实现原生屏幕录制功能,无需第三方插件或复杂后端支持。只需请求权限、合并媒体流、配置 recorder、处理数据块即可录制、播放和下载。配合格式检测、设备适配与 UI 提升,可搭建完整实用的前端录屏工具。