Skip to main content

显示当前时间

在你的应用中渲染 <Player> 时,必须采取特别的考虑,以防止当时间变化时应用或 <Player> 不断重新渲染。

🌐 When rendering a <Player> in your app, special considerations must be taken to prevent constant re-renders of the app or <Player> if the time changes.

这就是为什么 useCurrentFrame() 钩子在组合之外不起作用的原因。

🌐 This is why the useCurrentFrame() hook does not work outside a composition.

warning

不要将这个 hook 放入渲染 <Player> 的同一个组件中,否则你会看到持续的重新渲染。相反,应将其放入渲染 Player 的组件旁边的组件中。

将组件与播放器时间同步

🌐 Synchronizing a component with the Player time

如果你想显示一个与播放器时间同步的组件,例如时间线组件的光标或自定义时间显示,你可以使用以下钩子:

🌐 If you want to display a component that synchronizes with the time of the player, for example the cursor of a timeline component or a custom time display, you can use the following hook:

use-current-player-frame.ts
import {CallbackListener, PlayerRef} from '@remotion/player'; import {useCallback, useSyncExternalStore} from 'react'; export const useCurrentPlayerFrame = ( ref: React.RefObject<PlayerRef | null>, ) => { const subscribe = useCallback( (onStoreChange: () => void) => { const {current} = ref; if (!current) { return () => undefined; } const updater: CallbackListener<'frameupdate'> = ({detail}) => { onStoreChange(); }; current.addEventListener('frameupdate', updater); return () => { current.removeEventListener('frameupdate', updater); }; }, [ref], ); const data = useSyncExternalStore<number>( subscribe, () => ref.current?.getCurrentFrame() ?? 0, () => 0, ); return data; };

使用示例

🌐 Usage example

添加一个对 React Player 的引用并将其传递给另一个组件:

🌐 Add a ref to a React Player and pass it to another component:

import {Player, PlayerRef} from '@remotion/player';
import {useRef} from 'react';
import {MyVideo} from './remotion/MyVideo';
import {TimeDisplay} from './remotion/TimeDisplay';

export const App: React.FC = () => {
  const playerRef = useRef<PlayerRef>(null);

  return (
    <>
      <Player
        ref={playerRef}
        component={MyVideo}
        durationInFrames={120}
        compositionWidth={1920}
        compositionHeight={1080}
        fps={30}
      />
      <TimeDisplay playerRef={playerRef} />
    </>
  );
};

组件可以这样访问当前时间:

🌐 This is how a component could access the current time:

TimeDisplay.tsx
import React from 'react'; import {PlayerRef} from '@remotion/player'; import {useCurrentPlayerFrame} from './use-current-player-frame'; export const TimeDisplay: React.FC<{ playerRef: React.RefObject<PlayerRef | null>; }> = ({playerRef}) => { const frame = useCurrentPlayerFrame(playerRef); return <div>current frame: {frame}</div>; };

这种方法是高效的,因为只有视频本身和依赖时间的组件会重新渲染,而 <App> 组件不会。

🌐 This approach is efficient, because only the video itself and the component relying on the time are re-rendering, but the <App> component is not.