在現有專案中安裝 Remotion
了解如何將 Remotion 整合到現有的 React 應用程式中,包括 Next.js、React Router、Vite 和 Create React App,以及純 Node.js 伺服器端專案的安裝設定。
在現有專案中安裝 Remotion
Remotion 可以安裝到現有的專案中,例如 Next.js、React Router、Vite 或 Create React App,以及純 Node.js 伺服器端專案。
安裝套件
首先安裝核心套件:
# npm
npm i --save-exact remotion@4.0.445 @remotion/cli@4.0.445
# pnpm
pnpm i remotion@4.0.445 @remotion/cli@4.0.445
# bun
bun i remotion@4.0.445 @remotion/cli@4.0.445
# yarn
yarn --exact add remotion@4.0.445 @remotion/cli@4.0.445重要提示:
- 請確保
remotion和所有@remotion/*套件都更新至相同版本- 移除版本號前的所有
^字元,以避免版本衝突
根據你的使用需求,選擇性安裝以下套件:
- 在現有 React 應用中嵌入 Remotion 影片:安裝
@remotion/player - 使用 Node.js API 渲染影片:安裝
@remotion/renderer - 在 Remotion Lambda 上觸發渲染:安裝
@remotion/lambda
# 安裝 Player 支援
npm i --save-exact @remotion/player@4.0.445
# 安裝伺服器端渲染支援
npm i --save-exact @remotion/renderer@4.0.445
# 安裝 Lambda 支援
npm i --save-exact @remotion/lambda@4.0.445設定資料夾結構
為 Remotion 檔案建立一個新資料夾。它可以放在任何位置並使用任何名稱。在本範例中,我們將其命名為 remotion 並放在專案根目錄。在建立的資料夾中,建立以下 3 個檔案:
1. 建立合成元件
// remotion/Composition.tsx
export const MyComposition = () => {
return null;
};2. 建立根元件
// remotion/Root.tsx
import React from 'react';
import { Composition } from 'remotion';
import { MyComposition } from './Composition';
export const RemotionRoot: React.FC = () => {
return (
<>
<Composition
id="Empty"
component={MyComposition}
durationInFrames={60}
fps={30}
width={1280}
height={720}
/>
</>
);
};3. 建立入口點
// remotion/index.ts
import { registerRoot } from "remotion";
import { RemotionRoot } from "./Root";
registerRoot(RemotionRoot);呼叫 registerRoot() 的檔案現在就是你的 Remotion 入口點。
注意:請留意
tsconfig.json中的 import 別名設定,確保import {...} from "remotion"不會解析到 remotion 資料夾。建議不要使用沒有前綴的路徑別名。
啟動 Remotion Studio
使用以下指令啟動 Remotion Studio:
npx remotion studio remotion/index.ts如有需要,請將 remotion/index.ts 替換為你的入口點路徑。
渲染影片
使用以下指令渲染影片:
npx remotion render remotion/index.ts MyComp out.mp4請將入口點、合成名稱和輸出檔名替換為符合你使用情境的值。
安裝 ESLint 外掛
Remotion 提供了一個 ESLint 外掛,可以警告不正確的 Remotion API 使用方式。要將其加入現有專案,請安裝:
# npm
npm i -D @remotion/eslint-plugin
# yarn
yarn add -D @remotion/eslint-plugin
# pnpm
pnpm i -D @remotion/eslint-plugin在你的 ESLint 設定中,僅針對 Remotion 檔案啟用推薦規則:
// .eslintrc
{
"plugins": ["@remotion"],
"overrides": [
{
"files": ["remotion/*.{ts,tsx}"],
"extends": ["plugin:@remotion/recommended"]
}
]
}在 React 應用中嵌入 Remotion 影片
你可以使用 <Player> 元件在現有 React 專案中顯示 Remotion 影片:
import { Player } from '@remotion/player';
import { MyComposition } from './remotion/Composition';
export const VideoSection: React.FC = () => {
return (
<Player
component={MyComposition}
durationInFrames={60}
compositionWidth={1280}
compositionHeight={720}
fps={30}
controls
/>
);
};Next.js 特別注意事項
在 Next.js 中整合 Remotion 時,需要注意以下幾點:
設定 webpack
Next.js 使用 webpack,你可能需要在 next.config.js 中加入特定設定:
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config) => {
// 確保 Remotion 的依賴正確處理
config.resolve.alias = {
...config.resolve.alias,
};
return config;
},
};
module.exports = nextConfig;使用動態匯入
由於 Remotion 使用了僅在瀏覽器中可用的 API,建議在 Next.js 中使用動態匯入並停用 SSR:
import dynamic from 'next/dynamic';
const Player = dynamic(
() => import('@remotion/player').then((mod) => mod.Player),
{ ssr: false }
);
export const VideoPage: React.FC = () => {
return (
<Player
component={MyComposition}
durationInFrames={60}
compositionWidth={1280}
compositionHeight={720}
fps={30}
controls
/>
);
};Vite 特別注意事項
在使用 Vite 的專案(如 React + Vite)中,通常不需要特別設定,直接安裝和使用即可。
// src/App.tsx
import { Player } from '@remotion/player';
import { MyComposition } from './remotion/Composition';
function App() {
return (
<div className="app">
<Player
component={MyComposition}
durationInFrames={60}
compositionWidth={1280}
compositionHeight={720}
fps={30}
controls
/>
</div>
);
}
export default App;完整的 Remotion 資料夾範例
以下是一個完整的 Remotion 資料夾結構範例,展示如何組織有多個合成的專案:
// remotion/HelloWorld.tsx
import { AbsoluteFill, useCurrentFrame, interpolate } from 'remotion';
interface HelloWorldProps {
message: string;
}
export const HelloWorld: React.FC<HelloWorldProps> = ({ message }) => {
const frame = useCurrentFrame();
const opacity = interpolate(frame, [0, 30], [0, 1], {
extrapolateRight: 'clamp',
});
return (
<AbsoluteFill
style={{
backgroundColor: 'white',
justifyContent: 'center',
alignItems: 'center',
}}
>
<div style={{ fontSize: 60, opacity }}>{message}</div>
</AbsoluteFill>
);
};// remotion/Root.tsx
import React from 'react';
import { Composition } from 'remotion';
import { MyComposition } from './Composition';
import { HelloWorld } from './HelloWorld';
export const RemotionRoot: React.FC = () => {
return (
<>
<Composition
id="Empty"
component={MyComposition}
durationInFrames={60}
fps={30}
width={1280}
height={720}
/>
<Composition
id="HelloWorld"
component={HelloWorld}
durationInFrames={90}
fps={30}
width={1280}
height={720}
defaultProps={{
message: '你好,世界!',
}}
/>
</>
);
};// remotion/index.ts
import { registerRoot } from "remotion";
import { RemotionRoot } from "./Root";
registerRoot(RemotionRoot);