Remotion LabRemotion Lab
其他偵測 Remotion 環境

偵測 Remotion 環境

如何在程式碼中判斷目前是否在 Remotion 渲染環境中執行,以分離渲染邏輯與非渲染邏輯。

偵測 Remotion 環境

在某些情況下,你的程式碼可能同時運行在 Remotion 渲染環境和一般瀏覽器環境(如 Remotion Player)中。了解如何偵測目前的執行環境,有助於根據情境執行不同的邏輯。

使用 getRemotionEnvironment()

Remotion 提供了 getRemotionEnvironment() 函式,可以取得目前的執行環境資訊:

import { getRemotionEnvironment } from "remotion";
 
const env = getRemotionEnvironment();
 
console.log(env.isRendering);  // 是否在進行幀渲染
console.log(env.isPlayer);     // 是否在 Remotion Player 中執行
console.log(env.isStudio);     // 是否在 Remotion Studio 中執行

各環境的回傳值

環境isRenderingisPlayerisStudio
renderMedia() 渲染中truefalsefalse
Remotion Playerfalsetruefalse
Remotion Studiofalsefalsetrue
一般瀏覽器(非 Remotion)falsefalsefalse

常見應用場景

場景一:分析工具只在非渲染時載入

import { getRemotionEnvironment } from "remotion";
import { useEffect } from "react";
 
export const MyVideo: React.FC = () => {
  useEffect(() => {
    const { isRendering } = getRemotionEnvironment();
 
    if (!isRendering) {
      // 只在預覽/播放時載入分析工具,渲染時不載入
      import("./analytics").then(({ initAnalytics }) => {
        initAnalytics();
      });
    }
  }, []);
 
  return <div>影片內容</div>;
};

場景二:渲染時使用靜態資料,預覽時使用動態資料

import { getRemotionEnvironment } from "remotion";
import { useState, useEffect } from "react";
 
interface VideoProps {
  staticData?: DataItem[];
}
 
export const DataDrivenVideo: React.FC<VideoProps> = ({ staticData }) => {
  const [data, setData] = useState<DataItem[]>(staticData || []);
  const { isRendering } = getRemotionEnvironment();
 
  useEffect(() => {
    if (!isRendering && !staticData) {
      // 非渲染環境才發出 API 請求(渲染時應透過 inputProps 傳入資料)
      fetch("/api/data")
        .then((r) => r.json())
        .then(setData);
    }
  }, [isRendering, staticData]);
 
  return (
    <div>
      {data.map((item) => (
        <div key={item.id}>{item.title}</div>
      ))}
    </div>
  );
};

場景三:效能最佳化——只在渲染時啟用高品質模式

import { getRemotionEnvironment } from "remotion";
 
export const QualityAwareComponent: React.FC = () => {
  const { isRendering } = getRemotionEnvironment();
 
  return (
    <canvas
      style={{
        // 渲染時使用高解析度,預覽時使用較低解析度以提升效能
        imageRendering: isRendering ? "pixelated" : "auto",
        width: "100%",
        height: "100%",
      }}
    />
  );
};

場景四:記錄操作日誌

import { getRemotionEnvironment } from "remotion";
 
function logEvent(event: string) {
  const { isRendering, isPlayer } = getRemotionEnvironment();
 
  // 渲染時不記錄日誌(避免在伺服器端產生大量日誌)
  if (isRendering) return;
 
  if (isPlayer) {
    console.log(`[Player] ${event}`);
  } else {
    console.log(`[App] ${event}`);
  }
}

使用 window.__remotion_globalThis 偵測(進階)

在不依賴 React Context 的情況下,可以透過全域變數偵測是否在 Remotion 渲染環境中:

function isInRemotionRender(): boolean {
  return typeof window !== "undefined" && "__remotion_globalThis" in window;
}

但更推薦使用官方的 getRemotionEnvironment() API。

使用環境變數

若你需要在 webpack 打包時就決定行為(而非執行時動態判斷),可以使用環境變數:

// 只在渲染環境打包的程式碼
if (process.env.REMOTION_ENV === "render") {
  // 渲染專用邏輯
}

remotion.config.ts 中設定:

import { Config } from "@remotion/cli/config";
 
Config.overrideWebpackConfig((config) => {
  return {
    ...config,
    plugins: [
      ...(config.plugins || []),
      new webpack.DefinePlugin({
        "process.env.REMOTION_ENV": JSON.stringify("render"),
      }),
    ],
  };
});

避免在渲染時執行副作用

在 Remotion 渲染過程中,每一幀都會被獨立渲染。某些副作用(如儲存資料到資料庫)不應該在渲染幀時執行:

import { getRemotionEnvironment, useCurrentFrame } from "remotion";
import { useEffect } from "react";
 
export const VideoWithSideEffect: React.FC = () => {
  const frame = useCurrentFrame();
  const { isRendering } = getRemotionEnvironment();
 
  useEffect(() => {
    // 只在 Player 播放時執行,不在渲染時執行
    if (!isRendering && frame === 0) {
      // 記錄影片播放開始
      trackVideoView();
    }
  }, [frame, isRendering]);
 
  return <div>影片內容</div>;
};

小結

  • 使用 getRemotionEnvironment() 取得目前執行環境的資訊。
  • isRendering:用於區分幀渲染與預覽播放的行為。
  • isPlayer:用於在 Remotion Player 中執行特定邏輯。
  • isStudio:用於在 Remotion Studio 中執行特定邏輯。
  • 避免在 isRenderingtrue 時執行網路請求或副作用。