{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "video-player",
  "title": "Video Player",
  "description": "A custom video player component.",
  "dependencies": [
    "motion",
    "lucide-react"
  ],
  "registryDependencies": [
    "button"
  ],
  "files": [
    {
      "path": "registry/ui/video-player.tsx",
      "content": "\"use client\"\nimport React, { useRef, useState } from \"react\"\nimport { Button } from \"@/components/ui/button\" // Internal path\nimport { Play, Pause, Volume2, Volume1, VolumeX } from \"lucide-react\"\nimport { motion, AnimatePresence } from \"motion/react\"\nimport { cn } from \"@/lib/utils\"\n\nconst formatTime = (seconds: number) => {\n  const minutes = Math.floor(seconds / 60)\n  const remainingSeconds = Math.floor(seconds % 60)\n  return `${minutes}:${remainingSeconds.toString().padStart(2, \"0\")}`\n}\n\nconst CustomSlider = ({\n  value,\n  onChange,\n  className,\n}: {\n  value: number\n  onChange: (value: number) => void\n  className?: string\n}) => {\n  return (\n    <motion.div\n      className={cn(\n        \"bg-secondary relative h-1 w-full cursor-pointer rounded-full\",\n        className,\n      )}\n      onClick={(e) => {\n        const rect = e.currentTarget.getBoundingClientRect()\n        const x = e.clientX - rect.left\n        const percentage = (x / rect.width) * 100\n        onChange(Math.min(Math.max(percentage, 0), 100))\n      }}\n    >\n      <motion.div\n        className=\"bg-primary absolute top-0 left-0 h-full rounded-full\"\n        style={{ width: `${value}%` }}\n        initial={{ width: 0 }}\n        animate={{ width: `${value}%` }}\n        transition={{ type: \"spring\", stiffness: 300, damping: 30 }}\n      />\n    </motion.div>\n  )\n}\n\nconst VideoPlayer = ({ src }: { src: string }) => {\n  const videoRef = useRef<HTMLVideoElement>(null)\n  const [isPlaying, setIsPlaying] = useState(false)\n  const [volume, setVolume] = useState(1)\n  const [progress, setProgress] = useState(0)\n  const [isMuted, setIsMuted] = useState(false)\n  const [playbackSpeed, setPlaybackSpeed] = useState(1)\n  const [showControls, setShowControls] = useState(false)\n  const [currentTime, setCurrentTime] = useState(0)\n  const [duration, setDuration] = useState(0)\n\n  const togglePlay = () => {\n    if (videoRef.current) {\n      if (isPlaying) {\n        videoRef.current.pause()\n      } else {\n        videoRef.current.play()\n      }\n      setIsPlaying(!isPlaying)\n    }\n  }\n\n  const handleVolumeChange = (value: number) => {\n    if (videoRef.current) {\n      const newVolume = value / 100\n      videoRef.current.volume = newVolume\n      setVolume(newVolume)\n      setIsMuted(newVolume === 0)\n    }\n  }\n\n  const handleTimeUpdate = () => {\n    if (videoRef.current) {\n      const progress =\n        (videoRef.current.currentTime / videoRef.current.duration) * 100\n      setProgress(Number.isFinite(progress) ? progress : 0)\n      setCurrentTime(videoRef.current.currentTime)\n      setDuration(videoRef.current.duration)\n    }\n  }\n\n  const handleSeek = (value: number) => {\n    if (videoRef.current?.duration) {\n      const time = (value / 100) * videoRef.current.duration\n      if (Number.isFinite(time)) {\n        videoRef.current.currentTime = time\n        setProgress(value)\n      }\n    }\n  }\n\n  const toggleMute = () => {\n    if (videoRef.current) {\n      videoRef.current.muted = !isMuted\n      setIsMuted(!isMuted)\n      if (!isMuted) {\n        setVolume(0)\n      } else {\n        setVolume(1)\n        videoRef.current.volume = 1\n      }\n    }\n  }\n\n  const setSpeed = (speed: number) => {\n    if (videoRef.current) {\n      videoRef.current.playbackRate = speed\n      setPlaybackSpeed(speed)\n    }\n  }\n\n  return (\n    <motion.div\n      className=\"bg-card border-border relative mx-auto w-full max-w-4xl overflow-hidden rounded-xl border shadow-sm backdrop-blur-sm\"\n      initial={{ opacity: 0, y: 20 }}\n      animate={{ opacity: 1, y: 0 }}\n      transition={{ duration: 0.5 }}\n      onMouseEnter={() => setShowControls(true)}\n      onMouseLeave={() => setShowControls(false)}\n    >\n      <video\n        ref={videoRef}\n        className=\"w-full\"\n        onTimeUpdate={handleTimeUpdate}\n        src={src}\n        onClick={togglePlay}\n        onKeyDown={(e) => {\n          if (e.key === \"Enter\" || e.key === \" \") {\n            e.preventDefault()\n            togglePlay()\n          }\n        }}\n      >\n        <track kind=\"captions\" />\n      </video>\n      <AnimatePresence>\n        {showControls && (\n          <motion.div\n            className=\"bg-background/80 border-border absolute right-0 bottom-0 left-0 m-2 mx-auto max-w-xl rounded-2xl border p-4 backdrop-blur-md\"\n            initial={{ y: 20, opacity: 0, filter: \"blur(10px)\" }}\n            animate={{ y: 0, opacity: 1, filter: \"blur(0px)\" }}\n            exit={{ y: 20, opacity: 0, filter: \"blur(10px)\" }}\n            transition={{ duration: 0.6, ease: \"circInOut\", type: \"spring\" }}\n          >\n            <div className=\"mb-2 flex items-center gap-2\">\n              <span className=\"text-foreground text-sm\">\n                {formatTime(currentTime)}\n              </span>\n              <CustomSlider\n                value={progress}\n                onChange={handleSeek}\n                className=\"flex-1\"\n              />\n              <span className=\"text-foreground text-sm\">\n                {formatTime(duration)}\n              </span>\n            </div>\n            <div className=\"flex items-center justify-between\">\n              <div className=\"flex items-center gap-4\">\n                <motion.div\n                  whileHover={{ scale: 1.1 }}\n                  whileTap={{ scale: 0.9 }}\n                >\n                  <Button\n                    onClick={togglePlay}\n                    variant=\"ghost\"\n                    size=\"icon\"\n                    className=\"text-foreground hover:bg-accent hover:text-accent-foreground\"\n                  >\n                    {isPlaying ? (\n                      <Pause className=\"h-5 w-5\" />\n                    ) : (\n                      <Play className=\"h-5 w-5\" />\n                    )}\n                  </Button>\n                </motion.div>\n                <div className=\"flex items-center gap-x-1\">\n                  <motion.div\n                    whileHover={{ scale: 1.1 }}\n                    whileTap={{ scale: 0.9 }}\n                  >\n                    <Button\n                      onClick={toggleMute}\n                      variant=\"ghost\"\n                      size=\"icon\"\n                      className=\"text-foreground hover:bg-accent hover:text-accent-foreground\"\n                    >\n                      {isMuted ? (\n                        <VolumeX className=\"h-5 w-5\" />\n                      ) : volume > 0.5 ? (\n                        <Volume2 className=\"h-5 w-5\" />\n                      ) : (\n                        <Volume1 className=\"h-5 w-5\" />\n                      )}\n                    </Button>\n                  </motion.div>\n                  <div className=\"w-24\">\n                    <CustomSlider\n                      value={volume * 100}\n                      onChange={handleVolumeChange}\n                    />\n                  </div>\n                </div>\n              </div>\n              <div className=\"flex items-center gap-2\">\n                {[0.5, 1, 1.5, 2].map((speed) => (\n                  <motion.div\n                    whileHover={{ scale: 1.1 }}\n                    whileTap={{ scale: 0.9 }}\n                    key={speed}\n                  >\n                    <Button\n                      onClick={() => setSpeed(speed)}\n                      variant=\"ghost\"\n                      size=\"icon\"\n                      className={cn(\n                        \"text-foreground hover:bg-accent hover:text-accent-foreground\",\n                        playbackSpeed === speed && \"bg-accent\",\n                      )}\n                    >\n                      {speed}x\n                    </Button>\n                  </motion.div>\n                ))}\n              </div>\n            </div>\n          </motion.div>\n        )}\n      </AnimatePresence>\n    </motion.div>\n  )\n}\n\nexport default VideoPlayer\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}