import { useCallback, useEffect, useRef, useState } from "react"; import { cn } from "@/lib/utils"; interface MotionPhotoPlayerProps { posterUrl: string; motionUrl: string; alt: string; presentationTimestampUs?: bigint; containerClassName?: string; mediaClassName?: string; posterClassName?: string; videoClassName?: string; active?: boolean; loop?: boolean; } const MotionPhotoPlayer = ({ posterUrl, motionUrl, alt, presentationTimestampUs, containerClassName, mediaClassName, posterClassName, videoClassName, active, loop = false, }: MotionPhotoPlayerProps) => { const videoRef = useRef(null); const [isPlaying, setIsPlaying] = useState(false); const resetPlaybackPosition = useCallback( (video: HTMLVideoElement) => { const startTime = presentationTimestampUs && presentationTimestampUs > 0n ? Number(presentationTimestampUs) / 1_000_000 : 0; video.currentTime = startTime; }, [presentationTimestampUs], ); const stopPlayback = useCallback( (resetPosition = true) => { const video = videoRef.current; if (!video) { return; } video.pause(); if (resetPosition && video.readyState >= 1) { resetPlaybackPosition(video); } setIsPlaying(false); }, [resetPlaybackPosition], ); const startPlayback = useCallback( async (loop: boolean) => { const video = videoRef.current; if (!video) { return; } video.loop = loop; if (video.readyState >= 1) { resetPlaybackPosition(video); } try { await video.play(); setIsPlaying(true); } catch { setIsPlaying(false); } }, [resetPlaybackPosition], ); useEffect(() => stopPlayback, [stopPlayback]); useEffect(() => { if (!active) { stopPlayback(); return; } void startPlayback(loop); }, [active, loop, startPlayback, stopPlayback]); return (
{alt}
); }; export default MotionPhotoPlayer;