显示当前时间
在应用程序中呈现<Player>
时,必须特别考虑防止应用程序或<Player>
因时间更改而不断重新渲染。
这就是为什么useCurrentFrame()
钩子在组合之外不起作用。
warning
不要将此钩子放入呈现<Player>
的同一组件中,否则您将看到不断重新渲染。相反,将其放入呈现Player
的组件旁边的组件中。
与Player时间同步的 组件
如果要显示与播放器时间同步的组件,例如时间轴组件的光标或自定义时间显示,可以使用以下钩子:
use-current-player-frame.tstsx
import {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.tstsx
import {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添加到引用中并将其传递给另一个组件:
tsx
import {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 } /></>);};
tsx
import {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.tsxtsx
importReact 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.tsxtsx
importReact 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>
组件不会重新渲染。