使用 SSR API 進行渲染
使用 @remotion/renderer 套件的 Node.js API 在伺服器端渲染 Remotion 影片、音訊和圖片序列
使用 SSR API 進行渲染
NPM 套件 @remotion/renderer 提供了在伺服器端渲染 Remotion 影片的 API。這些函數可在 Node.js 和 Bun 中使用。
渲染流程
渲染影片需要三個步驟:
- 建立 Bundle(打包 Remotion 專案)
- 選擇要渲染的合成並計算其元數據
- 渲染影片、音訊、靜態圖片或圖片序列
完整範例
以下是帶有注釋的完整渲染腳本:
import { bundle } from '@remotion/bundler';
import { renderMedia, selectComposition } from '@remotion/renderer';
import path from 'path';
// 要渲染的合成 ID
const compositionId = 'HelloWorld';
// 您只需建立一次 bundle,可以複用它
// 透過傳入不同的 input props 對多個渲染進行參數化
const bundleLocation = await bundle({
entryPoint: path.resolve('./src/index.ts'),
// 如果您在 remotion.config.ts 中有 webpack 覆蓋設定,也在此處傳入
webpackOverride: (config) => config,
});
// 透過傳入 props 對影片進行參數化
const inputProps = {
title: 'Hello World',
subtitle: 'Made with Remotion',
};
// 獲取要渲染的合成
// 如果您想自訂時長或其他元數據,請傳入 inputProps
const composition = await selectComposition({
serveUrl: bundleLocation,
id: compositionId,
inputProps,
});
// 渲染影片
// 如果您的影片使用了資料參數化,再次傳入相同的 inputProps
await renderMedia({
composition,
serveUrl: bundleLocation,
codec: 'h264',
outputLocation: `out/${compositionId}.mp4`,
inputProps,
});
console.log('渲染完成!');安裝必要套件
npm install @remotion/renderer @remotion/bundler核心 API 說明
bundle()
打包您的 Remotion 專案:
import { bundle } from '@remotion/bundler';
const bundleLocation = await bundle({
entryPoint: path.resolve('./src/index.ts'),
webpackOverride: (config) => config, // 可選的 webpack 覆蓋
onProgress: (progress) => {
console.log(`打包進度:${progress}%`);
},
});Bundle 可以在多次渲染間複用,只要程式碼沒有變更。
selectComposition()
選擇並獲取合成的元數據:
import { selectComposition } from '@remotion/renderer';
const composition = await selectComposition({
serveUrl: bundleLocation,
id: 'MyComposition',
inputProps: { /* 您的 props */ },
timeoutInMilliseconds: 30000, // 可選,預設 30 秒
});
console.log(composition.durationInFrames); // 合成幀數
console.log(composition.fps); // 幀率
console.log(composition.width); // 寬度
console.log(composition.height); // 高度renderMedia()
渲染影片或音訊:
import { renderMedia } from '@remotion/renderer';
await renderMedia({
composition,
serveUrl: bundleLocation,
codec: 'h264', // 'h264' | 'h265' | 'vp8' | 'vp9' | 'mp3' | 'aac' | 'wav' | 'prores' | 'gif'
outputLocation: 'out/video.mp4',
inputProps: { /* 您的 props */ },
onProgress: ({ progress }) => {
console.log(`渲染進度:${Math.round(progress * 100)}%`);
},
concurrency: 1, // 並發渲染的瀏覽器頁面數
timeoutInMilliseconds: 30000,
});renderStill()
渲染單張靜態圖片:
import { renderStill } from '@remotion/renderer';
await renderStill({
composition,
serveUrl: bundleLocation,
frame: 30, // 要渲染的幀
output: 'out/still.png',
inputProps: { /* 您的 props */ },
});效能調優
並發渲染
await renderMedia({
composition,
serveUrl: bundleLocation,
codec: 'h264',
outputLocation: 'out/video.mp4',
concurrency: 4, // 同時使用 4 個瀏覽器頁面
});複用 Bundle
// 一次打包,多次渲染
const bundleLocation = await bundle({ entryPoint: './src/index.ts' });
// 渲染多個影片
await Promise.all([
renderMedia({ serveUrl: bundleLocation, composition: comp1, /* ... */ }),
renderMedia({ serveUrl: bundleLocation, composition: comp2, /* ... */ }),
]);複用瀏覽器實例
import { openBrowser, renderMedia } from '@remotion/renderer';
const browser = await openBrowser('chrome');
for (const video of videoList) {
await renderMedia({
composition: video.composition,
serveUrl: bundleLocation,
codec: 'h264',
outputLocation: video.output,
browserExecutable: browser,
});
}
await browser.close();錯誤處理
try {
await renderMedia({
composition,
serveUrl: bundleLocation,
codec: 'h264',
outputLocation: 'out/video.mp4',
});
} catch (err) {
if (err instanceof Error) {
console.error('渲染失敗:', err.message);
// 錯誤訊息包含詳細的堆疊追蹤資訊
}
}