Cloud Run 生成渲染
在 Google Cloud Run 上觸發 Remotion 渲染任務,包含 API 呼叫方式、渲染參數設定與輸出檔案處理。
Cloud Run 生成渲染
本文說明如何透過 CLI 或 Node.js API 在 Google Cloud Run 上觸發影片與靜態圖片的渲染工作。
前置準備
在觸發渲染之前,請確認已完成:
- Cloud Run 服務已部署
- Remotion 專案已上傳為站台(
sites create) - 環境變數(GCP 憑證)已正確設定
使用 CLI 渲染影片
npx remotion cloudrun render \
https://storage.googleapis.com/my-bucket/sites/my-site/index.html \
MyComposition \
--region=asia-east1輸出影片預設會上傳至與站台相同的 Cloud Storage Bucket。
指定輸出格式與編解碼器:
npx remotion cloudrun render \
https://storage.googleapis.com/my-bucket/sites/my-site/index.html \
MyComposition \
--codec=h264 \
--region=asia-east1 \
--out=renders/output.mp4使用 Node.js API 渲染影片
import { renderMediaOnCloudrun } from "@remotion/cloudrun";
const result = await renderMediaOnCloudrun({
region: "asia-east1",
serviceName: "remotion-render-4-0-0",
serveUrl:
"https://storage.googleapis.com/my-bucket/sites/my-site/index.html",
composition: "MyComposition",
codec: "h264",
inputProps: {
title: "我的影片標題",
backgroundColor: "#1a1a2e",
},
});
if (result.type === "success") {
console.log("輸出網址:", result.publicUrl);
console.log("Cloud Storage 路徑:", result.cloudStorageUri);
console.log("渲染時間:", result.renderId);
}渲染靜態圖片
使用 renderStillOnCloudrun() 渲染單一幀:
import { renderStillOnCloudrun } from "@remotion/cloudrun";
const result = await renderStillOnCloudrun({
region: "asia-east1",
serviceName: "remotion-render-4-0-0",
serveUrl:
"https://storage.googleapis.com/my-bucket/sites/my-site/index.html",
composition: "MyThumbnail",
frame: 0,
imageFormat: "png",
inputProps: {
title: "縮圖標題",
},
});
if (result.type === "success") {
console.log("圖片網址:", result.publicUrl);
}常用渲染參數
影片輸出參數
| 參數 | 型別 | 說明 |
|---|---|---|
codec | string | 編解碼器,如 h264、vp8、vp9、gif |
inputProps | object | 傳入 Composition 的 props |
outputLocation | string | 輸出路徑(Cloud Storage) |
privacy | string | "public" 或 "private" |
envVariables | object | 傳入渲染環境的環境變數 |
timeoutInMilliseconds | number | 單幀渲染逾時時間(毫秒) |
chromiumOptions | object | Chromium 啟動選項 |
scale | number | 輸出解析度縮放比例(預設 1) |
frameRange | [number, number] | 只渲染指定幀範圍 |
靜態圖片輸出參數
| 參數 | 型別 | 說明 |
|---|---|---|
frame | number | 要渲染的幀數 |
imageFormat | string | "png"、"jpeg" 或 "webp" |
jpegQuality | number | JPEG 品質(1–100) |
scale | number | 輸出解析度縮放比例 |
傳入動態 Props
const result = await renderMediaOnCloudrun({
region: "asia-east1",
serviceName: "remotion-render-4-0-0",
serveUrl: "https://storage.googleapis.com/...",
composition: "NewsVideo",
codec: "h264",
inputProps: {
headline: "台灣科技新聞",
reporter: "王小明",
date: new Date().toISOString(),
items: [
{ title: "新品發表", duration: 150 },
{ title: "市場分析", duration: 200 },
],
},
});設定輸出路徑與存取權限
const result = await renderMediaOnCloudrun({
region: "asia-east1",
serviceName: "remotion-render-4-0-0",
serveUrl: "https://storage.googleapis.com/...",
composition: "MyComposition",
codec: "h264",
// 指定輸出路徑格式
outName: `renders/${Date.now()}/output.mp4`,
// 設定為公開存取
privacy: "public",
});只渲染部分幀
const result = await renderMediaOnCloudrun({
region: "asia-east1",
serviceName: "remotion-render-4-0-0",
serveUrl: "https://storage.googleapis.com/...",
composition: "MyComposition",
codec: "h264",
// 只渲染第 0–149 幀(5 秒,30fps)
frameRange: [0, 149],
});批量渲染
對多個輸入同時觸發渲染:
import { renderMediaOnCloudrun } from "@remotion/cloudrun";
const videos = [
{ id: "user1", title: "用戶一的影片", color: "#ff6b6b" },
{ id: "user2", title: "用戶二的影片", color: "#4ecdc4" },
{ id: "user3", title: "用戶三的影片", color: "#45b7d1" },
];
const results = await Promise.all(
videos.map((video) =>
renderMediaOnCloudrun({
region: "asia-east1",
serviceName: "remotion-render-4-0-0",
serveUrl: "https://storage.googleapis.com/...",
composition: "PersonalVideo",
codec: "h264",
inputProps: video,
outName: `renders/${video.id}.mp4`,
})
)
);
results.forEach((result, i) => {
if (result.type === "success") {
console.log(`${videos[i].id}: ${result.publicUrl}`);
}
});處理渲染結果
const result = await renderMediaOnCloudrun({ ... });
if (result.type === "success") {
// 公開可存取的 URL
const publicUrl = result.publicUrl;
// Cloud Storage URI(gs://...)
const storageUri = result.cloudStorageUri;
// 渲染 ID(用於日誌查詢)
const renderId = result.renderId;
// 將 URL 存入資料庫
await db.renders.create({
renderId,
publicUrl,
createdAt: new Date(),
});
} else if (result.type === "crash") {
console.error("渲染崩潰:", result.message);
}小結
- 使用
renderMediaOnCloudrun()渲染影片,renderStillOnCloudrun()渲染靜態圖片 - 透過
inputProps傳入動態資料 outName和privacy控制輸出路徑與存取權限- 使用
Promise.all()並行執行批量渲染 - 渲染結果包含
publicUrl與cloudStorageUri