JavaScript 前端录屏完整指南:使用 MediaRecorder API 实现屏幕录制功能

为什么使用 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 提升,可搭建完整实用的前端录屏工具。

评论