免安裝外掛:如何用 HTML5 MediaRecorder 實作「線上螢幕錄影」工具

發布日期: 2026年6月30日
難度: 中高級
所需時間: 約 35-45 分鐘


前言

不論是要製作線上教學影片、錄製軟體報錯(Bug)畫面,還是存取網頁視訊會議,螢幕錄影已經是日常不可或缺的功能。過去,我們可能需要安裝 OBS 等專業錄影軟體,或是安裝瀏覽器擴充外掛。

這篇文章將手把手帶領大家使用 HTML5 原生的 Screen Capture APIMediaRecorder API,開發出一個完全免安裝外掛、無廣告、資料純本地端處理(無隱私外洩風險),且同時支援麥克風與系統音訊雙重混音錄製的個人專屬「線上螢幕錄影工具」!


核心技術:HTML5 媒體串流 API

要在瀏覽器中完成錄影,主要依賴以下三個核心 API:

1. navigator.mediaDevices.getDisplayMedia()

  • 這是原生的螢幕分享 API。調用時,瀏覽器會安全地跳出視窗,詢問使用者要錄製「整個螢幕」、「特定應用程式視窗」或是「單一瀏覽器分頁」。

2. navigator.mediaDevices.getUserMedia()

  • 用於取得使用者的麥克風音訊(人聲輸入)。

3. MediaRecorder

  • 負責將獲取到的視訊與音訊媒體串流(MediaStream)打包編碼,並即時切片成二進位數據塊(Chunks),最後整合成影片檔案供下載。

第一步:規劃使用者介面 (HTML5 + CSS)

我們打造出具備毛玻璃(Glassmorphism)與霓虹發光感(Pulsing Glow)的現代排版:

  • 左側設定面板:包含音訊切換開關、錄影狀態顯示、電子計時器(Timer)、以及開始/暫停/停止按鈕。
  • 右側視訊工作區:包含即時影像預覽器與未錄製時的動態 Placeholder。
<div class="app-container">
    <!-- 左側錄影控制台 -->
    <div class="card controls-panel">
        <h2><i class="fa-solid fa-sliders"></i> 錄製設定</h2>
        <!-- 麥克風與系統音訊開關 -->
        <div class="dashboard-info">
            <span class="status-dot" id="status-dot"></span>
            <div class="dashboard-timer" id="timer">00:00:00</div>
        </div>
        <!-- 錄影控制按鈕群 -->
    </div>
    
    <!-- 右側預覽播放器 -->
    <div class="card video-container-wrapper">
        <video id="video-preview" autoplay playsinline muted></video>
    </div>
</div>

第二步:混音技術 (Audio Mixing)

在進行螢幕錄影時,常見的需求是同時錄製電腦聲音(如遊戲音效、分頁音樂)與我們講話的聲音(麥克風)

這需要使用 HTML5 的 AudioContext 來進行合流混音,否則錄影軌道會因為衝突而只能保留其中一種聲音:

// 1. 取得麥克風人聲串流
const micStream = await navigator.mediaDevices.getUserMedia({ audio: true });

// 2. 取得螢幕與系統音效串流
const screenStream = await navigator.mediaDevices.getDisplayMedia({ video: true, audio: true });

// 3. 建立 AudioContext 並進行混音
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
const destination = audioCtx.createMediaStreamDestination();

// 將麥克風聲音連接至混音器
const micSource = audioCtx.createMediaStreamSource(micStream);
micSource.connect(destination);

// 將系統/分頁聲音連接至混音器
const screenSource = audioCtx.createMediaStreamSource(screenStream);
screenSource.connect(destination);

// 4. 組合最終包含視訊軌道與混音後音訊軌道的 Stream
const videoTrack = screenStream.getVideoTracks()[0];
const mixedAudioTrack = destination.stream.getAudioTracks()[0];

const combinedStream = new MediaStream([videoTrack, mixedAudioTrack]);

這段混音架構能完美合併麥克風音訊與分頁音訊,讓錄製好的影片同時擁有環境人聲與系統伴奏。


第三步:使用 MediaRecorder 錄製影片

獲得 combinedStream 後,即可開始初始化 MediaRecorder。我們優先使用編碼效率高、解析度出色的 WebM (VP9/Opus) 編碼:

let recordedChunks = [];
let mediaRecorder = null;

// 優先選用高壓縮率的 VP9,不支援則退回預設 WebM
let options = { mimeType: 'video/webm;codecs=vp9,opus' };
if (!MediaRecorder.isTypeSupported(options.mimeType)) {
    options = { mimeType: 'video/webm' };
}

mediaRecorder = new MediaRecorder(combinedStream, options);

// 每秒鐘即時收集一次錄影的數據碎片
mediaRecorder.ondataavailable = function(e) {
    if (e.data && e.data.size > 0) {
        recordedChunks.push(e.data);
    }
};

// 停止錄影時的處理邏輯
mediaRecorder.onstop = function() {
    // 1. 關閉所有媒體軌道以釋放攝影機、螢幕分享與麥克風佔用
    screenStream.getTracks().forEach(t => t.stop());
    if (micStream) micStream.getTracks().forEach(t => t.stop());

    // 2. 將收集到的二進位碎片合併為一個影片 Blob
    const blob = new Blob(recordedChunks, { type: 'video/webm' });
    const videoURL = URL.createObjectURL(blob);
    
    // 3. 將預覽器改為播放模式,允許使用者即時拉動進度條與監聽聲音
    videoPreview.srcObject = null;
    videoPreview.src = videoURL;
    videoPreview.controls = true;
    videoPreview.muted = false; // 允許播放聲音
};

// 開始錄影!
mediaRecorder.start(1000);

第四步:監聽瀏覽器「停止分享」按鈕

這是一個非常重要的細節。當我們開始錄影時,瀏覽器底部會跳出一個「停止分享」的系統浮動吧。如果使用者點選了它,我們必須即時捕捉到這個動作並主動觸存影片,否則錄影會當掉:

// 監聽螢幕視訊軌道的 ended 事件
videoTrack.onended = function() {
    stopRecording(); // 主動呼叫停止錄製邏輯,確保已錄內容不遺失
};

第五步:Nginx 部署與無快取策略

為了能讓工具在生產環境中秒速加載且即時更新,我們將應用程式託管在 Nginx 伺服器的 /recorder/ 資料夾下,並設定禁止快取標頭

# 停用螢幕錄影等工具的快取,確保版本迭代即時更新
location ~* ^/(collage|qrcode|cropper|cropper-circle|recorder)/.*\.html$ {
    add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
    expires -1;
}

這能保證使用者每次造訪工具,載入的都是瀏覽器最精準、修復過後的程式碼版本。


結語

利用原生 HTML5 API 的強大能力,我們不需要依賴任何第三方伺服器,只花費大約 200 行代碼就在客戶端完成了螢幕捕獲、麥克風合流、即時編碼與影片導出。

  • 拒絕浮水印:完全開源無限制,導出影片乾淨無瑕。
  • 拒絕隱私外洩:影片編碼完全在您本機瀏覽器沙盒中完成,沒有任何資料會上傳到雲端,隱私極致安全。
  • 多功能控制:支援音訊自選開關、即時解析度反饋與時間儀表板。

*歡迎前往我們的產生器頁面測試使用:(https://stillbuilding.life/recorder/)*

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

返回頂端