前端录屏黑科技:几行 JS 代码就能实现!


在过去,想要在网页上实现“录屏”功能,往往需要借助复杂的浏览器插件、桌面应用或者付费的第三方服务。这不仅增加了用户的操作成本,也给开发者带来了不小的挑战。但如今,随着
Web API 的不断发展,一个强大的原生工具已经悄然来到了我们身边—— ** MediaRecorder API ** 。

什么是 MediaRecorder API?

MediaRecorder 是 WebRTC(Web Real-Time Communication)技术栈的一部分。简单来说,它是一个可以接收
** 媒体流(MediaStream) ** ,并将其编码成特定格式(如 WebM 或 MP4),然后以数据块(Blobs)的形式输出的接口。

这里的媒体流来源非常广泛,可以是:

  • 用户的摄像头和麦克风 ( navigator.mediaDevices.getUserMedia )
  • ** 用户的屏幕、窗口或浏览器标签页 ( navigator.mediaDevices.getDisplayMedia ) **
  • 网页中的 <video><audio> 元素
  • 甚至是一个动态生成的 Canvas 画布

而我们要实现的“录屏”功能,正是利用了第二种来源—— getDisplayMedia API。

实现一个基础的录屏功能:三步走

实现一个基础的录屏功能,核心逻辑可以分为三步: ** 获取流 -> 录制流 -> 处理结果 ** 。

第一步:获取屏幕共享的媒体流

首先,我们需要向用户申请权限,以获取他们屏幕内容的媒体流。 getDisplayMedia API
会弹出一个浏览器原生的对话框,让用户选择要共享的屏幕、窗口或标签页。

// 1. 获取屏幕共享流的函数  
async function getScreenStream() {  
    try {  
        // 提示用户选择要共享的屏幕或窗口  
        const stream = await navigator.mediaDevices.getDisplayMedia({  
            video: true, // 必须,表示我们要捕获视频  
            audio: true // 可选,表示我们想同时捕获该屏幕播放的音频  
        });  
        return stream;  
    } catch (error) {  
        console.error("获取屏幕共享失败:", error);  
        alert("您取消了屏幕共享或发生了错误。");  
        return null;  
    }  
}  

** 注意 ** : getDisplayMedia 必须由用户交互(如点击按钮)触发,否则浏览器会出于安全考虑而阻止它。

第二步:创建 MediaRecorder 实例并开始录制

获取到 MediaStream 对象后,我们就可以用它来创建一个 MediaRecorder 实例。

第三步:停止录制并处理结果

当用户点击停止按钮或关闭屏幕共享时,我们调用 mediaRecorder.stop() 。录制的数据块会汇集在 recordedChunks 数组中,我们只需将它们整合成一个 Blob 对象,就可以生成最终的视频文件。

// 3. 停止录制的函数  
function stopRecording() {  
    if (mediaRecorder && mediaRecorder.state !== 'inactive') {  
        mediaRecorder.stop();  
    }  
}  
  
// 4. 处理录制结果  
function handleRecordingStop() {  
    // 将所有数据块合并成一个 Blob  
    const recordedBlob = new Blob(recordedChunks, { type: 'video/webm' });  
  
    // 创建一个 URL,用于预览或下载  
    const videoUrl = URL.createObjectURL(recordedBlob);  
  
    // 例如,创建一个下载链接  
    const downloadLink = document.createElement('a');  
    downloadLink.href = videoUrl;  
    downloadLink.download = `recording-${new Date().toISOString()}.webm`;  
    downloadLink.textContent = '下载录屏';  
    document.body.appendChild(downloadLink);  
      
    // 或者创建一个 video 元素进行预览  
    const previewVideo = document.createElement('video');  
    previewVideo.src = videoUrl;  
    previewVideo.controls = true;  
    document.body.appendChild(previewVideo);  
  
    // 清空数据块,为下一次录制做准备  
    recordedChunks = [];  
}  

将这三步与 UI 按钮(开始、停止)结合起来,一个完整的网页录屏应用就诞生了!

MediaRecorder 的应用场景远不止于此,比如可以用它来实现:用户反馈与 Bug 复现、在线教育与演示等。

注意事项与最佳实践

  1. ** 浏览器兼容性 ** : MediaRecorder API 在现代浏览器(Chrome, Firefox, Edge, Safari)中得到了广泛支持,但仍需检查兼容性,并为不支持的浏览器提供优雅降级。
  2. ** MIME 类型 ** :不同的浏览器支持不同的 mimeType 。可以使用 MediaRecorder.isTypeSupported() 方法来检查支持情况,并选择最合适的格式。 video/webm 是最广泛支持的。
  3. ** 用户授权 ** :始终在用户明确操作后才调用 getDisplayMedia ,并清晰地告知用户为何需要此权限。
  4. ** 资源管理 ** :录制完成后,记得使用 URL.revokeObjectURL() 释放由 createObjectURL 创建的 URL,避免内存泄漏。同时,确保停止媒体流( stream.getTracks().forEach(track => track.stop()) ),关闭摄像头或屏幕共享的指示灯。
  5. ** 性能考量 ** :长时间或高分辨率的录制会消耗大量内存和 CPU。对于需要上传的场景,可以考虑分片上传,而不是等待整个文件录制完毕。