useVideo
Supplies a video ref with playback, timing, mute, volume, seeking, and fullscreen controls.
About
useVideo is a compact controller for one stable <video> element. It mirrors time, duration, play/pause state and exposes synchronous control functions for common media operations.
Example
import { useVideo } from "rooks";
export default function VideoPlayer() {
const [videoRef, video, controls] = useVideo();
return (
<section>
<video ref={videoRef} src="/example-video.mp4" controls width={480}>
<track
kind="captions"
src="/example-captions.vtt"
srcLang="en"
label="English"
default
/>
</video>
<p aria-live="polite">
{video.isPaused ? "Paused" : "Playing"} at{" "}
{Math.round(video.currentTime)} of {Math.round(video.duration)} seconds
</p>
<button
type="button"
onClick={video.isPaused ? controls.play : controls.pause}
>
{video.isPaused ? "Play" : "Pause"}
</button>
<button type="button" onClick={() => controls.rewind(10)}>
Back 10 seconds
</button>
<button type="button" onClick={() => controls.fastForward(10)}>
Forward 10 seconds
</button>
<button type="button" onClick={controls.toggleMute}>
{video.isMuted ? "Unmute" : "Mute"}
</button>
</section>
);
}The media and captions paths represent assets supplied by the application.
Parameters
This hook accepts no parameters. The video source and native element properties belong on the <video> element.
Return value
Returns [videoRef, state, controls].
videoRefis an object ref for anHTMLVideoElement.statecontainscurrentTimeandduration(initially0),isPaused(initiallytrue),isMuted(initiallyfalse), andvolume(initially1).controlscontainsplay,pause,toggleMute,setVolume,setCurrentTime,fastForward,rewind, andtoggleFullScreen. Every control returnsvoid.
These state and control shape names are internal and cannot be imported from rooks.
Behavior and lifecycle
After mount, the hook subscribes to timeupdate, durationchange, pause, and play on the referenced video and removes those listeners on unmount. Keep the ref attached to the same video for the hook's lifetime; changing only videoRef.current does not rerun the listener effect.
Controls do nothing while the ref is null. setVolume does not clamp its argument, and seeking helpers do not clamp time; invalid assignments follow browser behavior and can throw. play() and fullscreen methods ignore their platform promises, so this hook does not expose autoplay, permission, or fullscreen rejection errors. Native volume or mute changes are not subscribed to and can leave those two state fields stale unless the hook's controls made the change.
Compatibility and accessibility
The initial tuple is safe to render on the server, and controls are inert until a client element attaches. Playback and fullscreen generally require user activation; toggleFullScreen() also requires Fullscreen API support. Use useFullscreen when promise handling and availability state are required, or usePictureInPictureApi for PiP support and errors.
Prefer native media controls or provide equivalent keyboard operation, names, focus indication, captions, and transcripts. Do not rely only on the hook's mirrored state to report playback errors. See SSR and browser APIs.
Related
- useAudio offers richer callbacks, clamping, loading, buffering, rate, and error state.
- usePictureInPictureApi manages Picture-in-Picture for the same video ref.
- useFullscreen exposes support and promise-returning fullscreen controls.