前端錄屏黑科技:幾行 JS 代碼就能實現(xiàn)!
在過去,想要在網(wǎng)頁上實現(xiàn)“錄屏”功能,往往需要借助復(fù)雜的瀏覽器插件、桌面應(yīng)用或者付費(fèi)的第三方服務(wù)。這不僅增加了用戶的操作成本,也給開發(fā)者帶來了不小的挑戰(zhàn)。但如今,隨著 Web API 的不斷發(fā)展,一個強(qiáng)大的原生工具已經(jīng)悄然來到了我們身邊——MediaRecorder API。

1. 什么是 MediaRecorder API?
MediaRecorder 是 WebRTC(Web Real-Time Communication)技術(shù)棧的一部分。簡單來說,它是一個可以接收媒體流(MediaStream),并將其編碼成特定格式(如 WebM 或 MP4),然后以數(shù)據(jù)塊(Blobs)的形式輸出的接口。
這里的媒體流來源非常廣泛,可以是:
- 用戶的攝像頭和麥克風(fēng) (navigator.mediaDevices.getUserMedia)
 - 用戶的屏幕、窗口或瀏覽器標(biāo)簽頁 (navigator.mediaDevices.getDisplayMedia)
 - 網(wǎng)頁中的 <video> 或 <audio> 元素
 - 甚至是一個動態(tài)生成的 Canvas 畫布
 
而我們要實現(xiàn)的“錄屏”功能,正是利用了第二種來源——getDisplayMedia API。
2. 實現(xiàn)一個基礎(chǔ)的錄屏功能:三步走
實現(xiàn)一個基礎(chǔ)的錄屏功能,核心邏輯可以分為三步:獲取流 -> 錄制流 -> 處理結(jié)果。
第一步:獲取屏幕共享的媒體流
首先,我們需要向用戶申請權(quán)限,以獲取他們屏幕內(nèi)容的媒體流。getDisplayMedia API 會彈出一個瀏覽器原生的對話框,讓用戶選擇要共享的屏幕、窗口或標(biāo)簽頁。
// 1. 獲取屏幕共享流的函數(shù)
async function getScreenStream() {
    try {
        // 提示用戶選擇要共享的屏幕或窗口
        const stream = await navigator.mediaDevices.getDisplayMedia({
            video: true, // 必須,表示我們要捕獲視頻
            audio: true // 可選,表示我們想同時捕獲該屏幕播放的音頻
        });
        return stream;
    } catch (error) {
        console.error("獲取屏幕共享失敗:", error);
        alert("您取消了屏幕共享或發(fā)生了錯誤。");
        return null;
    }
}注意:getDisplayMedia 必須由用戶交互(如點擊按鈕)觸發(fā),否則瀏覽器會出于安全考慮而阻止它。
第二步:創(chuàng)建 MediaRecorder 實例并開始錄制
獲取到 MediaStream 對象后,我們就可以用它來創(chuàng)建一個 MediaRecorder 實例。

第三步:停止錄制并處理結(jié)果
當(dāng)用戶點擊停止按鈕或關(guān)閉屏幕共享時,我們調(diào)用 mediaRecorder.stop()。錄制的數(shù)據(jù)塊會匯集在 recordedChunks 數(shù)組中,我們只需將它們整合成一個 Blob 對象,就可以生成最終的視頻文件。
// 3. 停止錄制的函數(shù)
function stopRecording() {
    if (mediaRecorder && mediaRecorder.state !== 'inactive') {
        mediaRecorder.stop();
    }
}
// 4. 處理錄制結(jié)果
function handleRecordingStop() {
    // 將所有數(shù)據(jù)塊合并成一個 Blob
    const recordedBlob = new Blob(recordedChunks, { type: 'video/webm' });
    // 創(chuàng)建一個 URL,用于預(yù)覽或下載
    const videoUrl = URL.createObjectURL(recordedBlob);
    // 例如,創(chuàng)建一個下載鏈接
    const downloadLink = document.createElement('a');
    downloadLink.href = videoUrl;
    downloadLink.download = `recording-${new Date().toISOString()}.webm`;
    downloadLink.textContent = '下載錄屏';
    document.body.appendChild(downloadLink);
    
    // 或者創(chuàng)建一個 video 元素進(jìn)行預(yù)覽
    const previewVideo = document.createElement('video');
    previewVideo.src = videoUrl;
    previewVideo.controls = true;
    document.body.appendChild(previewVideo);
    // 清空數(shù)據(jù)塊,為下一次錄制做準(zhǔn)備
    recordedChunks = [];
}將這三步與 UI 按鈕(開始、停止)結(jié)合起來,一個完整的網(wǎng)頁錄屏應(yīng)用就誕生了!
MediaRecorder 的應(yīng)用場景遠(yuǎn)不止于此,比如可以用它來實現(xiàn):用戶反饋與 Bug 復(fù)現(xiàn)、在線教育與演示等。
3. 注意事項與優(yōu)秀實踐
- 瀏覽器兼容性:MediaRecorder API 在現(xiàn)代瀏覽器(Chrome, Firefox, Edge, Safari)中得到了廣泛支持,但仍需檢查兼容性,并為不支持的瀏覽器提供優(yōu)雅降級。
 - MIME 類型:不同的瀏覽器支持不同的 mimeType??梢允褂?nbsp;MediaRecorder.isTypeSupported() 方法來檢查支持情況,并選擇最合適的格式。video/webm 是最廣泛支持的。
 - 用戶授權(quán):始終在用戶明確操作后才調(diào)用 getDisplayMedia,并清晰地告知用戶為何需要此權(quán)限。
 - 資源管理:錄制完成后,記得使用 URL.revokeObjectURL() 釋放由 createObjectURL 創(chuàng)建的 URL,避免內(nèi)存泄漏。同時,確保停止媒體流(stream.getTracks().forEach(track => track.stop())),關(guān)閉攝像頭或屏幕共享的指示燈。
 - 性能考量:長時間或高分辨率的錄制會消耗大量內(nèi)存和 CPU。對于需要上傳的場景,可以考慮分片上傳,而不是等待整個文件錄制完畢。
 















 
 
 








 
 
 
 