显示当前时间
在应用程序中呈现<Player>时,必须特别考虑防止应用程序或<Player>因时间更改而不断重新渲染。
这就是为什么useCurrentFrame()钩子在组合之外不起作用。
warning
不要将此钩子放入呈现<Player>的同一组件中,否则您将看到不断重新渲染。相反,将其放入呈现Player的组件旁边的组件中。
与Player时间同步的 组件
如果要显示与播放器时间同步的组件,例如时间轴组件的光标或自定义时间显示,可以使用以下钩子:
use-current-player-frame.tstsximport {CallbackListener ,PlayerRef } from "@remotion/player";import {useCallback ,useSyncExternalStore } from "react";export constuseCurrentPlayerFrame = (ref :React .RefObject <PlayerRef >) => {constsubscribe =useCallback ((onStoreChange : () => void) => {const {current } =ref ;if (!current ) {return () =>undefined ;}constupdater :CallbackListener <"frameupdate"> = ({detail }) => {onStoreChange ();};current .addEventListener ("frameupdate",updater );return () => {current .removeEventListener ("frameupdate",updater );};},[ref ]);constdata =useSyncExternalStore <number>(subscribe ,() =>ref .current ?.getCurrentFrame () ?? 0,() => 0);returndata ;};
use-current-player-frame.tstsximport {CallbackListener ,PlayerRef } from "@remotion/player";import {useCallback ,useSyncExternalStore } from "react";export constuseCurrentPlayerFrame = (ref :React .RefObject <PlayerRef >) => {constsubscribe =useCallback ((onStoreChange : () => void) => {const {current } =ref ;if (!current ) {return () =>undefined ;}constupdater :CallbackListener <"frameupdate"> = ({detail }) => {onStoreChange ();};current .addEventListener ("frameupdate",updater );return () => {current .removeEventListener ("frameupdate",updater );};},[ref ]);constdata =useSyncExternalStore <number>(subscribe ,() =>ref .current ?.getCurrentFrame () ?? 0,() => 0);returndata ;};
使用示例
将React Player添加到引用中并将其传递给另一个组件:
tsximport {Player ,PlayerRef } from "@remotion/player";import {useRef } from "react";import {MyVideo } from "./remotion/MyVideo";import {TimeDisplay } from "./remotion/TimeDisplay";export constApp :React .FC = () => {constplayerRef =useRef <PlayerRef >(null);return (<><Player ref ={playerRef }component ={MyVideo }durationInFrames ={120}compositionWidth ={1920}compositionHeight ={1080}fps ={30}/><TimeDisplay playerRef ={playerRef } /></>);};
tsximport {Player ,PlayerRef } from "@remotion/player";import {useRef } from "react";import {MyVideo } from "./remotion/MyVideo";import {TimeDisplay } from "./remotion/TimeDisplay";export constApp :React .FC = () => {constplayerRef =useRef <PlayerRef >(null);return (<><Player ref ={playerRef }component ={MyVideo }durationInFrames ={120}compositionWidth ={1920}compositionHeight ={1080}fps ={30}/><TimeDisplay playerRef ={playerRef } /></>);};
这是组件如何访问当前时间的方式:
TimeDisplay.tsxtsximportReact from "react";import {PlayerRef } from "@remotion/player";import {useC layerFrame } from "./use-current-plaurrentP yer-fra me";export constTimeD lay:isp React .FC <{playerRef :React .RefObject <PlayerRef >;}> = ({playerRef }) => {constframe =useCurrentPlayerFrame (playerRef );return <div >current frame: {frame }</div >;};
TimeDisplay.tsxtsximportReact from "react";import {PlayerRef } from "@remotion/player";import {useC layerFrame } from "./use-current-plaurrentP yer-fra me";export constTimeD lay:isp React .FC <{playerRef :React .RefObject <PlayerRef >;}> = ({playerRef }) => {constframe =useCurrentPlayerFrame (playerRef );return <div >current frame: {frame }</div >;};
这种方法是高效的,因为只有视频本身和依赖于时间的组件会重新渲染,而<App>组件不会重新渲染。