Remotion LabRemotion Lab
客戶端渲染客戶端渲染運作原理

客戶端渲染運作原理

深入了解 Remotion 客戶端渲染的機制,包括像素捕捉、畫布繪製、音訊處理和編碼流程。

客戶端渲染運作原理

警告 — 實驗性功能:此功能隨時可能出現錯誤和重大變更。請在 GitHub 上追蹤進度,並在 Discord 的 #web-renderer 頻道中參與討論。

客戶端渲染最大的挑戰在於無法捕捉瀏覽器視窗畫面。只有特定的 HTML 元素(如 <canvas><img><video><svg>)可以被原生捕捉。

與伺服器端渲染(進行像素級精確的截圖)不同,客戶端渲染中 Remotion 會根據其對 DOM 中元素位置和外觀的判斷,將所有元素放置在畫布上。

為此,Remotion 開發了一套精密的演算法來計算元素在畫布上的位置。當然,我們無法支援所有網頁功能,因此只支援特定的元素和樣式子集

渲染流程

初始化

首先,元件被掛載到 DOM 中使用者不可見的位置,同時初始化一個空白畫布。

逐幀捕捉流程

對於每個需要渲染的幀,渲染器使用 element.createTreeWalker() 找出 DOM 中的所有元素和文字節點。設有 display: none 的節點及其子節點會被跳過。

對於每個可捕捉的元素,渲染器會執行以下步驟:

  1. 沿 DOM 樹向上查找,將所有 transform CSS 屬性重設為 none
  2. 使用 .getBoundingClientRect() 取得元素的邊界框,以及父元素的邊界框
  3. 累加所有 transform 和位置,以確定元素在 DOM 中的原始位置
  4. 取得元素的像素資料——對於 <svg><canvas><img> 元素,可直接捕捉;對於文字節點,則需手動重建佈局
  5. 根據計算出的位置將像素繪製至畫布

音訊捕捉

來自已掛載的 <Audio><Video> 元素的音訊會被捕捉並混合,然後加入影片的音軌。

編碼

Mediabunny 用於將幀和已處理的音訊編碼為影片檔案。

捕捉像素

對於 <svg><canvas><img> 元素,可使用廣泛記錄的技術原生捕捉像素。

對於其他類型的元素,只支援部分屬性,例如 backgroundborderborder-radius。這些樣式會使用 Canvas 2D API 手動繪製至畫布。

捕捉文字節點

對於文字節點,需要進行更多佈局計算。

通常無法直接取得文字節點的邊界框,但透過將文字節點包裝在 <span> 元素中,可以對 <span> 呼叫 .getBoundingClientRect() 來取得邊界框,並如上所述解析 transform。

然後使用 Intl.Segmenter 將文字分割為單詞,每個 token 再次被包裝在 <span> 中,對每個 token 呼叫 .getBoundingClientRect(),並將這些 token 繪製至畫布。

最後,DOM 會被重設為原始狀態。

Context 隔離

渲染發生在與你的應用程式相同的瀏覽器環境中。這意味著 CSS 和 Tailwind 變數會自動生效,但也存在與主頁面發生衝突的風險。

請參閱限制說明以了解更多詳情,確保你的程式碼能與客戶端渲染正常配合。

貢獻

如果你有興趣改進 Web 渲染器,例如添加新的樣式支援,請參閱客戶端渲染貢獻指南

相關資源