Remotion LabRemotion Lab
疑難排解常見問題疑難排解

常見問題疑難排解

Remotion 開發中常見問題的診斷與解決方法,涵蓋背景圖片閃爍、找不到編解碼器、媒體播放異常等議題。

本文匯整 Remotion 開發時最常遇到的問題與對應解法,協助你快速定位並排除障礙。


背景圖片或遮罩導致的閃爍問題

問題描述

在 Remotion 中,以下寫法是不建議使用的:

// ❌ 不建議這樣做
const myMarkup = (
  <div
    style={{
      backgroundImage: `url(${src})`,
    }}
  >
    <p>Hello World</p>
  </div>
);

原因

Remotion 在渲染時必須確保所有資源都已完全載入,才能截取畫面。然而,當你透過 CSS 的 background-imagemask-image 或其他 CSS 屬性來載入圖片時,Remotion 無法得知圖片何時載入完成。這會導致 Remotion 在圖片尚未載入完畢的情況下就截圖,產生肉眼可見的閃爍(flickering)現象。

解決方案:改用 <Img> 標籤搭配 <AbsoluteFill>

最直接的解法是改用 Remotion 提供的 <Img> 元件,並將圖片與內容分層疊放:

// ✅ 建議這樣做
import { AbsoluteFill, Img } from "remotion";
 
const myMarkup = (
  <AbsoluteFill>
    <AbsoluteFill>
      <Img
        style={{
          width: "100%",
        }}
        src={src}
      />
    </AbsoluteFill>
    <AbsoluteFill>
      <p>Hello World</p>
    </AbsoluteFill>
  </AbsoluteFill>
);

文字內容會疊加在圖片之上,且不會發生閃爍。

變通方案:無法使用 <Img>

有時候你必須使用 CSS 的 mask-image() 等屬性,無法直接改用 <Img>。這種情況下,可以在頁面上額外放置一個隱藏的 <Img> 標籤來觸發圖片的預先載入:

// ✅ 變通做法
import { Img } from "remotion";
 
const myMarkup = (
  <>
    <Img
      src={src}
      style={{
        opacity: 0,
        position: "absolute",
        left: "-100%",
      }}
    />
    <div
      style={{
        maskImage: `url(${src})`,
      }}
    >
      <p>Hello World</p>
    </div>
  </>
);

這個隱藏的 <Img> 標籤會確保圖片完整下載,讓 background-imagemask-image 能夠正確渲染。


找不到編解碼器(Codec Not Found)

問題描述

當你嘗試渲染影片時,可能出現類似以下的錯誤訊息:

Error: Could not find a codec for the given options.

或是:

Could not find encoder 'libx264'

原因分析

Remotion 在底層使用 FFmpeg 進行影片編碼。「找不到編解碼器」的錯誤通常由以下原因引起:

  1. FFmpeg 未安裝或版本不支援 — 你的系統上沒有安裝 FFmpeg,或是安裝的版本不包含所需的編解碼器(例如 libx264 需要 FFmpeg 在編譯時包含該函式庫)。
  2. 指定的編解碼器名稱錯誤 — 在 renderMedia() 或 CLI 中指定了不存在的編解碼器名稱。
  3. 作業系統或環境的限制 — 某些 Docker 映像或最小化環境僅包含有限的 FFmpeg 功能。

解決方案

確認 Remotion 使用的 FFmpeg 版本

Remotion 內建了一套 FFmpeg binaries(透過 @remotion/bundlerremotion 套件),不需要你另外安裝系統層級的 FFmpeg。如果你遇到編解碼器問題,先確認是否正確使用了 Remotion 提供的工具:

npx remotion versions

在 Docker 環境中

若在 Docker 容器中渲染,請參考官方的 Docker 設定指南,確保映像包含必要的系統依賴。

選擇合適的輸出格式

Remotion 支援多種輸出格式,如果某個編解碼器不可用,可以嘗試切換到其他格式:

import { renderMedia, selectComposition } from "@remotion/renderer";
 
const composition = await selectComposition({
  serveUrl,
  id: compositionId,
});
 
await renderMedia({
  composition,
  serveUrl,
  codec: "h264", // 可嘗試 'h264' | 'h265' | 'vp8' | 'vp9' | 'mp3' | 'aac' | 'wav' | 'prores' | 'gif'
  outputLocation: "out/video.mp4",
});

媒體播放問題

影片或音訊不同步

Remotion 的渲染機制是逐幀截圖,因此不存在傳統意義上的「播放」概念。如果你發現音視頻在最終輸出中不同步,請確認:

  1. 你的 <Audio><Video> 元件有正確設定 startFromendAt 屬性。
  2. Composition 的 fps 設定與預期一致。
  3. 使用 <OffthreadVideo> 替代 <Video> 可能解決某些同步問題。

媒體無法載入

如果你在 Remotion Studio 或渲染過程中發現媒體無法載入,請檢查:

  • 檔案路徑是否正確(使用 staticFile() 引用 public/ 目錄中的資源)
  • 媒體檔案是否支援 seeking(詳見不可 seek 的媒體
  • 是否有網路防火牆阻擋外部資源
import { Audio, staticFile } from "remotion";
 
// ✅ 正確引用本地媒體
export const MyComp = () => {
  return <Audio src={staticFile("my-audio.mp3")} />;
};

一般除錯技巧

使用 delayRender 追蹤非同步問題

如果某個畫面在渲染時需要等待非同步資料,請使用 delayRendercontinueRender

import { delayRender, continueRender } from "remotion";
import { useState, useEffect } from "react";
 
export const MyComp = () => {
  const [handle] = useState(() =>
    delayRender("Fetching data from API...")
  );
  const [data, setData] = useState(null);
 
  useEffect(() => {
    fetch("https://api.example.com/data")
      .then((res) => res.json())
      .then((json) => {
        setData(json);
        continueRender(handle);
      });
  }, []);
 
  if (!data) return null;
 
  return <div>{data.title}</div>;
};

在 Remotion Studio 中除錯

  • 使用瀏覽器的開發者工具(DevTools)查看 Console 中的錯誤訊息
  • 在 Remotion Studio 的時間軸上逐幀檢視,找出出問題的幀
  • 使用 console.log(useCurrentFrame()) 確認幀號是否如預期

升級 Remotion 版本

許多問題在較舊版本中存在,升級到最新版本往往能解決問題:

npm run upgrade

相關資源