可变的持续时间和尺寸
你可以根据一些异步确定的数据更改视频的时长。同样,视频的宽度、高度和帧率也是如此。
🌐 You may change the duration of the video based on some asynchronously determined data.
The same goes for the width, height and framerate of the video.
使用 calculateMetadata() 函数v4.0.0
🌐 Using the calculateMetadata() functionv4.0.0
考虑这样一种情景,其中视频被动态指定为背景,并且合成的持续时间应与视频的持续时间一致。
🌐 Consider a scenario where a video is dynamically specified as a background and the duration of the composition should be aligned with the duration of the video.
将一个 calculateMetadata 回调函数传递给 <Composition>。该函数应接受组合属性并计算元数据。
🌐 Pass a calculateMetadata callback function to a <Composition>. This function should take the combined props and calculate the metadata.
src/Root.tsximportReact from 'react'; import {Composition } from 'remotion'; import {Video } from '@remotion/media'; import {getMediaMetadata } from './get-media-metadata'; 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://remotion.media/BigBuckBunny.mp4', }}calculateMetadata ={async ({props }) => { const {durationInSeconds } = awaitgetMediaMetadata (props .src ); return {durationInFrames :Math .floor (durationInSeconds * 30), }; }} /> ); };
请参阅 使用 Mediabunny 获取元数据 来获取 get-media-metadata.ts 的代码片段。
props 默认为指定的 defaultProps,但可以通过 向渲染传递输入属性 来覆盖。
🌐 The props defaults to the defaultProps specified, but may be overriden by passing input props to the render.
返回一个带有 durationInFrames 的对象以更改视频的时长。
此外,或者作为替代,你也可以返回 fps、width 和 height 以更新视频的分辨率和帧率。
🌐 Return an object with durationInFrames to change the duration of the video.
In addition or instead, you may also return fps, width and height to update the video's resolution and framerate.
同时也可以通过返回一个 props 字段来转换传递给组件的 props(传递给组件的 props)。
🌐 It is also possible to transform the props passed to the component by returning a props field at the same time.
使用 useEffect() 和 getInputProps()
🌐 With useEffect() and getInputProps()
在以下示例中,Remotion 被指示在评估组合之前等待 getMediaMetadata() 的 Promise 解决。
🌐 In the following example, Remotion is instructed to wait for the getMediaMetadata() promise to resolve before evaluating the composition.
通过调用 delayRender(),Remotion 将被阻止继续,直到调用 continueRender() 为止。
🌐 By calling delayRender(), Remotion will be blocked from proceeding until continueRender() is called.
src/Root.tsximport {getMediaMetadata } from './get-media-metadata'; export constIndex :React .FC = () => { const [handle ] =useState (() =>delayRender ()); const [duration ,setDuration ] =useState (1);useEffect (() => {getMediaMetadata ('https://remotion.media/video.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 } />; };
请参阅 使用 Mediabunny 获取元数据 来获取 get-media-metadata.ts 的代码片段。
要动态传递视频资源,你可以在渲染时传递输入属性,并使用getInputProps()在你的 React 代码中获取它们。
🌐 To dynamically pass a video asset, you may pass input props when rendering and retrieve them inside your React code using getInputProps().
src/Root.tsximport {getInputProps } from 'remotion'; constinputProps =getInputProps (); constsrc =inputProps .src ;
缺点
🌐 Drawbacks
自 v4.0 起不再推荐使用此技术,因为 useEffect() 不仅在 Remotion 最初计算视频的元数据时执行,还会在生成渲染工作进程时执行。
🌐 This technique is not recommended anymore since v4.0, because the useEffect() does not only get executed when Remotion is initially calculating the metadata of the video, but also when spawning a render worker.
由于渲染进程可能高度并发,这可能导致不必要的 API 调用和速率限制。
🌐 Since a render process might be highly concurrent, this might lead to unnecessary API calls and rate limitations.
与尺寸覆盖一起使用
🌐 Using together with dimension overrides
诸如 --width 的覆盖参数将优先,并覆盖你使用 calculateMetadata() 设置的变量维度。
🌐 Override parameters such as --width will be given priority and override the variable dimensions you set using calculateMetadata().
[--scale](/docs/scaling) 参数优先级最高,并将在覆盖参数和 calculateMetadata() 之后应用。
🌐 The --scale parameter has the highest priority and will be applied after override parameters and calculateMetadata().
在视频设计完成后更改尺寸和帧率
🌐 Changing dimensions and FPS after the video was designed
如果你按照特定尺寸设计了视频,然后想要渲染不同的分辨率(例如 4K 而不是全高清),你可以使用 输出缩放。
🌐 If you designed your video with certain dimensions and then want to render a different resolution (e.g. 4K instead of Full HD), you can use output scaling.
如果你在设计视频时使用了特定的帧率,然后想要更改帧率,你应该重构合成以确保在更改帧率时时间保持不变。
🌐 If you designed your video with certain FPS and then want to change the frame rate, you should refactor the composition to ensure the timing stays the same with changing frame rates.
使用 <Player>
🌐 With the <Player>
如果传递给 <Player> 的元数据发生变化,它将会做出反应。有两种可行的方法可以动态设置 Player 的元数据:
🌐 The <Player> will react if the metadata being passed to it changes. There are two viable ways to do dynamically set the metadata of the Player:
useEffect() 执行数据获取:
MyApp.tsximportReact from 'react'; import {useEffect ,useState } from 'react'; import {Player } from '@remotion/player'; import {getMediaMetadata } from './get-media-metadata'; export constIndex :React .FC = () => { const [duration ,setDuration ] =useState (1);useEffect (() => {getMediaMetadata ('https://remotion.media/video.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() 函数,该函数重用自你的 Remotion 项目:
MyApp.tsximport {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',isRendering : true, }), ) .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 } />; };
另请参阅
🌐 See also