動態影片規格
用 calculateMetadata 根據 Props 或外部資料動態決定影片長度和解析度。
為什麼需要動態規格?
有時候你不知道影片應該多長——它取決於內容:
- 投影片數量決定影片長度
- 音訊長度決定影片長度
- API 回傳的資料量決定影片長度
calculateMetadata 讓你在渲染前根據 Props 動態計算這些值。
基本用法
import { CalculateMetadataFunction, Composition } from "remotion";
interface Props {
slides: string[];
secondsPerSlide: number;
}
const calculateMetadata: CalculateMetadataFunction<Props> = ({
props,
}) => {
return {
durationInFrames: props.slides.length * props.secondsPerSlide * 30,
};
};
// 在 Composition 中使用
<Composition
id="SlideShow"
component={SlideShow}
calculateMetadata={calculateMetadata}
defaultProps={{
slides: ["第一張", "第二張", "第三張"],
secondsPerSlide: 3,
}}
/>3 張投影片 × 3 秒 × 30fps = 270 幀。
可以覆蓋的屬性
calculateMetadata 可以回傳:
| 屬性 | 說明 |
|---|---|
durationInFrames | 影片總幀數 |
fps | 每秒幀數 |
width | 影片寬度 |
height | 影片高度 |
props | 修改後的 Props(可以注入額外資料) |
擷取外部資料
calculateMetadata 可以是 async 函數:
const calculateMetadata: CalculateMetadataFunction<Props> = async ({
props,
}) => {
const response = await fetch(props.apiUrl);
const data = await response.json();
return {
durationInFrames: data.items.length * 90,
props: {
...props,
data, // 把 API 資料注入 Props
},
};
};這樣元件就能直接從 Props 中取得資料,不需要在元件內部做 fetch。
根據音訊長度決定影片長度
import { getAudioDurationInSeconds } from "@remotion/media-utils";
const calculateMetadata: CalculateMetadataFunction<Props> = async ({
props,
}) => {
const duration = await getAudioDurationInSeconds(props.audioUrl);
return {
durationInFrames: Math.ceil(duration * 30),
fps: 30,
};
};取消機制
如果 Studio 中 Props 快速變化(例如使用者拖動滑桿),舊的 calculateMetadata 呼叫應該被取消。用 abortSignal:
const calculateMetadata: CalculateMetadataFunction<Props> = async ({
props,
abortSignal,
}) => {
const response = await fetch(props.apiUrl, {
signal: abortSignal,
});
const data = await response.json();
return { props: { ...props, data } };
};小結
calculateMetadata在渲染前動態計算影片規格- 可以覆蓋長度、fps、解析度和 Props
- 支援 async,可以擷取外部 API 資料
- 用
abortSignal處理快速變化的取消機制