import { useState, useEffect, useCallback } from "react"; import { Player } from "../player"; import { usePlayer } from "../usePlayer"; import { useThrottle } from "../../../functionUtils"; /** * * @param listenerId - A unique identifier for the listener. * @param playerId - (Optional) The ID of the player to observe. * @returns The current playback time in seconds. */ export const usePlayerCurrentTime = ( listenerId: string, playerId?: string ): { currentTime: number | null; cancel: () => void } => { const [currentTime, setCurrentTime] = useState(null); const player: Player = usePlayer(playerId); const updateCurrentTime = useCallback(() => { if (player) { const newCurrentTime = player.getContentPosition(); setCurrentTime(newCurrentTime); } }, [player]); // We update the current time every ~250ms since player can have rate set to 2x. // We update more often than 2x a second to avoid noticiable 'pulsation' in update, // since native level also updates the current time every ~250ms, // and combined with assorted delays it creates interference pattern. const { throttledFunction: throttledUpdate, cancel } = useThrottle( updateCurrentTime, 1000 / 4 ); useEffect(() => { if (player) { throttledUpdate(); const listeners = { onVideoProgress: () => { setCurrentTime(player.getContentPosition()); }, }; const id = `${listenerId}_player_current_time`; player.addListener({ id: id, listener: listeners, }); return () => { player.removeListener(id); cancel(); }; } }, [player, listenerId, throttledUpdate, cancel]); return { currentTime, cancel }; };