可变持续时间和尺寸
您可以根据一些异步确定的数据更改视频的持续时间。
同样适用于视频的宽度、高度和帧速率。
使用 calculateMetadata()
函数v4.0.0
考虑这样一个场景,视频被动态指定为背景,合成的持续时间应与视频的持续时间对齐。
将一个 calculateMetadata
回调函数传递给 <Composition>
。此函数应接受组合的 props并计算元数据。
src/Root.tsxtsx
import {getVideoMetadata } from "@remotion/media-utils";import {Composition ,Video } from "remotion";typeMyCompProps = {src : string;};constMyComp :React .FC <MyCompProps > = ({src }) => {return <Video src ={src } />;};export constRoot :React .FC = () => {return (<Composition id ="MyComp"component ={MyComp }durationInFrames ={300}fps ={30}width ={1920}height ={1080}defaultProps ={{src : "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",}}calculateMetadata ={async ({props }) => {constdata = awaitgetVideoMetadata (props .src );return {durationInFrames :Math .floor (data .durationInSeconds * 30),};}}/>);};
src/Root.tsxtsx
import {getVideoMetadata } from "@remotion/media-utils";import {Composition ,Video } from "remotion";typeMyCompProps = {src : string;};constMyComp :React .FC <MyCompProps > = ({src }) => {return <Video src ={src } />;};export constRoot :React .FC = () => {return (<Composition id ="MyComp"component ={MyComp }durationInFrames ={300}fps ={30}width ={1920}height ={1080}defaultProps ={{src : "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",}}calculateMetadata ={async ({props }) => {constdata = awaitgetVideoMetadata (props .src );return {durationInFrames :Math .floor (data .durationInSeconds * 30),};}}/>);};
props
默认为指定的 defaultProps
,但可以通过将输入 props 传递给渲染来覆盖。
返回一个带有 durationInFrames
的对象以更改视频的持续时间。
此外,您还可以返回 fps
、width
和 height
来更新视频的分辨率和帧速率。
还可以通过同时返回一个 props
字段转换传递给组件的 props。
使用 useEffect()
和 getInputProps()
在以下示例中,Remotion 被指示在评估合成之前等待 getVideoMetadata()
承诺解析。
通过调用 delayRender()
,Remotion 将被阻止继续进行,直到调用 continueRender()
。
src/Root.tsxtsx
import {getVideoMetadata } from "@remotion/media-utils";export constIndex :React .FC = () => {const [handle ] =useState (() =>delayRender ());const [duration ,setDuration ] =useState (1);useEffect (() => {getVideoMetadata ("https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",).then (({durationInSeconds }) => {setDuration (Math .round (durationInSeconds * 30));continueRender (handle );}).catch ((err ) => {console .log (`Error fetching metadata: ${err }`);});}, [handle ]);return (<Composition id ="dynamic-duration"component ={VideoTesting }width ={1080}height ={1080}fps ={30}durationInFrames ={duration }/>);};
src/Root.tsxtsx
import {getVideoMetadata } from "@remotion/media-utils";export constIndex :React .FC = () => {const [handle ] =useState (() =>delayRender ());const [duration ,setDuration ] =useState (1);useEffect (() => {getVideoMetadata ("https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",).then (({durationInSeconds }) => {setDuration (Math .round (durationInSeconds * 30));continueRender (handle );}).catch ((err ) => {console .log (`Error fetching metadata: ${err }`);});}, [handle ]);return (<Composition id ="dynamic-duration"component ={VideoTesting }width ={1080}height ={1080}fps ={30}durationInFrames ={duration }/>);};
要动态传递视频资产,您可以在渲染时传递输入 props,并在 React 代码中使用 getInputProps()
检索它们。
src/Root.tsxtsx
import {getInputProps } from "remotion";constinputProps =getInputProps ();constsrc =inputProps .src ;
src/Root.tsxtsx
import {getInputProps } from "remotion";constinputProps =getInputProps ();constsrc =inputProps .src ;
缺点
自 v4.0 起不再推荐使用此技术,因为 useEffect()
不仅在 Remotion 最初计算视频的元数据时执行,还在生成渲染工作者时执行。
由于渲染过程可能高度并发,这可能导致不必要的 API 调用和速率限制。
与尺寸覆盖一起使用
覆盖参数,如 --width
,将被优先考虑,并覆盖您使用 calculateMetadata()
设置的变量尺寸。
--scale
参数具有最高优先级,并将在覆盖参数和 calculateMetadata()
之后应用。
在设计视频后更改尺寸和 FPS
如果您使用特定尺寸设计了您的视频,然后希望以不同的分辨率进行渲染(例如 4K 而不是全高清),您可以使用 输出缩放。
如果您使用特定 FPS 设计了您的视频,然后想要更改帧速率,您可以使用 <FpsConverter>
片段。
使用 <Player>
<Player>
将在传递给它的元数据发生变化时做出反应。有两种可行的方法可以动态设置播放器的元数据:
useEffect()
进行数据获取:
MyApp.tsxtsx
import {getVideoMetadata } from "@remotion/media-utils";import {useEffect ,useState } from "react";import {Player } from "@remotion/player";export constIndex :React .FC = () => {const [duration ,setDuration ] =useState (1);useEffect (() => {getVideoMetadata ("https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",).then (({durationInSeconds }) => {setDuration (Math .round (durationInSeconds * 30));}).catch ((err ) => {console .log (`Error fetching metadata: ${err }`);});}, []);return (<Player component ={VideoTesting }compositionWidth ={1080}compositionHeight ={1080}fps ={30}durationInFrames ={duration }/>);};
MyApp.tsxtsx
import {getVideoMetadata } from "@remotion/media-utils";import {useEffect ,useState } from "react";import {Player } from "@remotion/player";export constIndex :React .FC = () => {const [duration ,setDuration ] =useState (1);useEffect (() => {getVideoMetadata ("https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",).then (({durationInSeconds }) => {setDuration (Math .round (durationInSeconds * 30));}).catch ((err ) => {console .log (`Error fetching metadata: ${err }`);});}, []);return (<Player component ={VideoTesting }compositionWidth ={1080}compositionHeight ={1080}fps ={30}durationInFrames ={duration }/>);};
calculateMetadata()
function reused from your Remotion project:
MyApp.tsxtsx
import {Player } from "@remotion/player";typeProps = {};constcalculateMetadataFunction :CalculateMetadataFunction <Props > = () => {return {props : {},durationInFrames : 1,width : 100,height : 100,fps : 30,};};typeMetadata = {durationInFrames : number;compositionWidth : number;compositionHeight : number;fps : number;props :Props ;};export constIndex :React .FC = () => {const [metadata ,setMetadata ] =useState <Metadata | null>(null);useEffect (() => {Promise .resolve (calculateMetadataFunction ({defaultProps : {},props : {},abortSignal : newAbortController ().signal ,compositionId : "MyComp",}),).then (({durationInFrames ,props ,width ,height ,fps }) => {setMetadata ({durationInFrames :durationInFrames as number,compositionWidth :width as number,compositionHeight :height as number,fps :fps as number,props :props asProps ,});}).catch ((err ) => {console .log (`Error fetching metadata: ${err }`);});}, []);if (!metadata ) {return null;}return <Player component ={VideoTesting } {...metadata } />;};
MyApp.tsxtsx
import {Player } from "@remotion/player";typeProps = {};constcalculateMetadataFunction :CalculateMetadataFunction <Props > = () => {return {props : {},durationInFrames : 1,width : 100,height : 100,fps : 30,};};typeMetadata = {durationInFrames : number;compositionWidth : number;compositionHeight : number;fps : number;props :Props ;};export constIndex :React .FC = () => {const [metadata ,setMetadata ] =useState <Metadata | null>(null);useEffect (() => {Promise .resolve (calculateMetadataFunction ({defaultProps : {},props : {},abortSignal : newAbortController ().signal ,compositionId : "MyComp",}),).then (({durationInFrames ,props ,width ,height ,fps }) => {setMetadata ({durationInFrames :durationInFrames as number,compositionWidth :width as number,compositionHeight :height as number,fps :fps as number,props :props asProps ,});}).catch ((err ) => {console .log (`Error fetching metadata: ${err }`);});}, []);if (!metadata ) {return null;}return <Player component ={VideoTesting } {...metadata } />;};