{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "use-media-controls",
  "title": "useMediaControls",
  "description": "A hook to control media elements",
  "files": [
    {
      "path": "registry/hooks/use-media-controls.ts",
      "content": "'use client'\n\nimport * as React from 'react'\n\ninterface MediaControls {\n  play: () => Promise<void>\n  pause: () => void\n  toggle: () => Promise<void>\n  stop: () => void\n  toggleMute: (isMuted?: boolean) => void\n  setVolume: (volume: number) => void\n  setCurrentTime: (time: number) => void\n  isPlaying: boolean\n  isMuted: boolean\n  volume: number\n  currentTime: number\n  duration: number\n}\n\nexport function useMediaControls(\n  mediaRef: React.RefObject<HTMLMediaElement | null>,\n): MediaControls {\n  const [state, setState] = React.useState({\n    isPlaying: false,\n    isMuted: false,\n    volume: 1,\n    currentTime: 0,\n    duration: 0,\n  })\n\n  React.useEffect(() => {\n    const media = mediaRef.current\n\n    if (!media)\n      return\n\n    const abortController = new AbortController()\n\n    media.addEventListener('play', () => setState(s => ({ ...s, isPlaying: true })), { signal: abortController.signal })\n    media.addEventListener('pause', () => setState(s => ({ ...s, isPlaying: false })), { signal: abortController.signal })\n    media.addEventListener('volumechange', () => setState(s => ({\n      ...s,\n      volume: media.volume,\n      isMuted: media.muted,\n    })), { signal: abortController.signal })\n    media.addEventListener('timeupdate', () => setState(s => ({ ...s, currentTime: media.currentTime })), { signal: abortController.signal })\n    media.addEventListener('durationchange', () => setState(s => ({ ...s, duration: media.duration })), { signal: abortController.signal })\n    media.addEventListener('ended', () => setState(s => ({ ...s, isPlaying: false })), { signal: abortController.signal })\n\n    setState({\n      isPlaying: !media.paused,\n      isMuted: media.muted,\n      volume: media.volume,\n      currentTime: media.currentTime,\n      duration: media.duration || 0,\n    })\n\n    return () => {\n      abortController.abort()\n    }\n  }, [mediaRef])\n\n  const play = React.useCallback(async () => {\n    if (mediaRef.current) {\n      await mediaRef.current.play()\n    }\n  }, [mediaRef])\n\n  const pause = React.useCallback(() => {\n    if (mediaRef.current) {\n      mediaRef.current.pause()\n    }\n  }, [mediaRef])\n\n  const toggle = React.useCallback(async () => {\n    if (mediaRef.current) {\n      if (state.isPlaying) {\n        mediaRef.current.pause()\n      }\n      else {\n        await mediaRef.current.play()\n      }\n    }\n  }, [mediaRef, state.isPlaying])\n\n  const stop = React.useCallback(() => {\n    if (mediaRef.current) {\n      mediaRef.current.pause()\n      mediaRef.current.currentTime = 0\n    }\n  }, [mediaRef])\n\n  const toggleMute = React.useCallback((isMuted?: boolean) => {\n    if (mediaRef.current) {\n      mediaRef.current.muted = isMuted ?? !mediaRef.current.muted\n    }\n  }, [mediaRef])\n\n  const setVolumeValue = React.useCallback((value: number) => {\n    if (mediaRef.current) {\n      mediaRef.current.volume = Math.max(0, Math.min(1, value))\n    }\n  }, [mediaRef])\n\n  const setCurrentTimeValue = React.useCallback((time: number) => {\n    if (mediaRef.current) {\n      mediaRef.current.currentTime = Math.max(0, Math.min(state.duration, time))\n    }\n  }, [mediaRef, state.duration])\n\n  return {\n    play,\n    pause,\n    toggle,\n    stop,\n    toggleMute,\n    setVolume: setVolumeValue,\n    setCurrentTime: setCurrentTimeValue,\n    ...state,\n  }\n}\n",
      "type": "registry:hook",
      "target": "hookas/use-media-controls.ts"
    }
  ],
  "type": "registry:hook"
}