Remotion LabRemotion Lab
AIRemotion 程式碼的即時編譯

Remotion 程式碼的即時編譯

將 AI 生成的 Remotion 元件字串在瀏覽器中動態編譯並即時渲染

Remotion 程式碼的即時編譯

如果您透過 LLM 生成了 Remotion 元件字串,可以在瀏覽器中即時編譯它,以便顯示即時預覽。

基本概念

假設您有以下 Remotion 元件的字串形式:

const MyComponent = () => {
  return <div style={{fontSize: 100}}>Hello</div>;
};

要讓此程式碼可執行,需要經過以下步驟:

  1. 使用 Babel 轉譯 JSX 和 TypeScript
  2. 使用 Function 建構子將字串轉為可執行函數
  3. 注入必要的依賴(React、Remotion API)
  4. 在 Remotion Player 中渲染

步驟一:使用 Babel 轉譯

首先,使用 @babel/standalone 進行轉譯:

import * as Babel from '@babel/standalone';
 
const transpiled = Babel.transform(code, {
  presets: ['react', 'typescript'],
});

轉譯後的結果大致如下:

'const MyComponent = () => { return React.createElement("div", {style: {fontSize: 100}}, "Hello"); };'

步驟二:使用 Function 建構子

使用 JavaScript 的 Function 建構子將字串轉為函數:

const createComponent = new Function('React', `
  ${transpiled.code}
  return MyComponent;
`);

這相當於建立了:

function createComponent(React) {
  const MyComponent = () => { return React.createElement("div", {style: {fontSize: 100}}, "Hello"); };
  return MyComponent;
}

呼叫此函數並傳入實際的 React 函式庫,使元件可用:

const Component = createComponent(React);

步驟三:注入 Remotion API

只有 React 還不夠用於動畫。Remotion 元件需要存取 useCurrentFrame()<AbsoluteFill> 等 API。所有在程式碼中使用的 API 都必須明確傳入。

以下是包含幾個 Remotion API 的範例:

import { AbsoluteFill, useCurrentFrame, spring } from 'remotion';
 
const createComponent = new Function(
  'React',
  'AbsoluteFill',
  'useCurrentFrame',
  'spring',
  `
  ${transpiled.code}
  return MyComponent;
`
);
 
const Component = createComponent(React, AbsoluteFill, useCurrentFrame, spring);

每個參數名稱都成為執行程式碼內的可用變數。

完整範例

import * as Babel from '@babel/standalone';
import React from 'react';
import {
  AbsoluteFill,
  useCurrentFrame,
  useVideoConfig,
  interpolate,
  spring,
} from 'remotion';
 
function compileRemotionComponent(code: string) {
  // 轉譯 JSX/TSX
  const { code: transpiled } = Babel.transform(code, {
    presets: ['react', 'typescript'],
  });
 
  // 建立帶有依賴注入的函數
  const createComponent = new Function(
    'React',
    'AbsoluteFill',
    'useCurrentFrame',
    'useVideoConfig',
    'interpolate',
    'spring',
    `
    ${transpiled}
    return MyComponent;
  `
  );
 
  // 注入所有依賴
  return createComponent(
    React,
    AbsoluteFill,
    useCurrentFrame,
    useVideoConfig,
    interpolate,
    spring
  );
}
 
// 使用範例
const aiGeneratedCode = `
const MyComponent = () => {
  const frame = useCurrentFrame();
  const opacity = interpolate(frame, [0, 30], [0, 1]);
  return (
    <AbsoluteFill style={{opacity, backgroundColor: 'blue'}}>
      <div style={{color: 'white', fontSize: 60}}>Hello AI!</div>
    </AbsoluteFill>
  );
};
`;
 
const DynamicComponent = compileRemotionComponent(aiGeneratedCode);

在 Remotion Player 中使用

import { Player } from '@remotion/player';
 
export const App = () => {
  return (
    <Player
      component={DynamicComponent}
      durationInFrames={60}
      fps={30}
      compositionWidth={1920}
      compositionHeight={1080}
    />
  );
};

安全性注意事項

使用 Function 建構子執行動態程式碼存在安全風險:

  • 只在受信任的環境中執行 AI 生成的程式碼
  • 考慮在沙盒環境(如 iframe)中執行
  • 對使用者輸入進行嚴格的驗證和清理
  • 限制可注入的依賴,避免暴露敏感 API

相關資源