批量渲染
從資料集批量產出多支影片。
什麼是批量渲染?
批量渲染是程式化影片最強大的應用之一:用同一個模板,搭配不同的資料,自動產出大量影片。
例如:
- 為每個員工產出個人化的生日影片
- 為每個產品產出展示影片
- 為每天的數據產出日報影片
基本流程
import { bundle } from "@remotion/bundler";
import { renderMedia, selectComposition } from "@remotion/renderer";
import path from "path";
const dataset = [
{ name: "Alice", message: "生日快樂!", color: "#6366f1" },
{ name: "Bob", message: "新年快樂!", color: "#ec4899" },
{ name: "Charlie", message: "恭喜升遷!", color: "#10b981" },
];
async function batchRender() {
const bundled = await bundle({
entryPoint: path.resolve("./src/index.ts"),
});
for (const [index, data] of dataset.entries()) {
console.log(`渲染 ${index + 1}/${dataset.length}: ${data.name}`);
const composition = await selectComposition({
serveUrl: bundled,
id: "GreetingCard",
inputProps: data,
});
await renderMedia({
composition,
serveUrl: bundled,
codec: "h264",
outputLocation: `out/${data.name}.mp4`,
inputProps: data,
});
}
console.log("全部渲染完成!");
}
batchRender();從 CSV/JSON 讀取資料
import fs from "fs";
// 從 JSON 檔案
const dataset = JSON.parse(
fs.readFileSync("data/items.json", "utf-8")
);
// 從 API
const response = await fetch("https://api.example.com/items");
const dataset = await response.json();效能優化
只打包一次
bundle() 是最耗時的步驟。確保在迴圈外面只呼叫一次:
// ✅ 正確:打包一次
const bundled = await bundle({ ... });
for (const data of dataset) {
await renderMedia({ serveUrl: bundled, ... });
}
// ❌ 錯誤:每次都重新打包
for (const data of dataset) {
const bundled = await bundle({ ... }); // 浪費時間!
await renderMedia({ serveUrl: bundled, ... });
}並行渲染多支影片
// 同時渲染 3 支影片
const CONCURRENT = 3;
const chunks = [];
for (let i = 0; i < dataset.length; i += CONCURRENT) {
chunks.push(dataset.slice(i, i + CONCURRENT));
}
for (const chunk of chunks) {
await Promise.all(
chunk.map((data) =>
renderMedia({
composition,
serveUrl: bundled,
codec: "h264",
outputLocation: `out/${data.name}.mp4`,
inputProps: data,
})
)
);
}小結
- 批量渲染是程式化影片的殺手級功能
- 只打包一次,然後用不同 Props 渲染多支影片
- 可以從 JSON、CSV 或 API 讀取資料
- 用 Promise.all 並行渲染提升效率