Rooks

useVideo

About

A comprehensive React hook for video control and state management. This hook provides a ref to attach to video elements, reactive state tracking, and a complete set of video control methods.

Examples

Basic video player

import { useVideo } from "rooks";
import React from "react";
 
export default function App() {
  const [videoRef, videoState, videoControls] = useVideo();
 
  return (
    <div style={{ padding: "20px" }}>
      <h1>Basic Video Player</h1>
      <video
        ref={videoRef}
        width="400"
        height="300"
        src="https://www.w3schools.com/html/mov_bbb.mp4"
        controls={false}
      />
      <div style={{ marginTop: "10px" }}>
        <p>Current Time: {videoState.currentTime.toFixed(2)}s</p>
        <p>Duration: {videoState.duration.toFixed(2)}s</p>
        <p>Status: {videoState.isPaused ? "Paused" : "Playing"}</p>
        <p>Volume: {(videoState.volume * 100).toFixed(0)}%</p>
        <p>Muted: {videoState.isMuted ? "Yes" : "No"}</p>
      </div>
      <div style={{ marginTop: "10px", display: "flex", gap: "10px" }}>
        <button onClick={videoControls.play}>Play</button>
        <button onClick={videoControls.pause}>Pause</button>
        <button onClick={videoControls.toggleMute}>Toggle Mute</button>
        <button onClick={videoControls.toggleFullScreen}>Fullscreen</button>
      </div>
    </div>
  );
}

Advanced video player with seek controls

import { useVideo } from "rooks";
import React from "react";
 
export default function App() {
  const [videoRef, videoState, videoControls] = useVideo();
 
  const handleSeek = (event) => {
    const seekTime = parseFloat(event.target.value);
    videoControls.setCurrentTime(seekTime);
  };
 
  const handleVolumeChange = (event) => {
    const newVolume = parseFloat(event.target.value);
    videoControls.setVolume(newVolume);
  };
 
  return (
    <div style={{ padding: "20px", maxWidth: "600px" }}>
      <h1>Advanced Video Player</h1>
      <video
        ref={videoRef}
        width="100%"
        height="300"
        src="https://www.w3schools.com/html/mov_bbb.mp4"
        controls={false}
      />
      
      {/* Progress bar */}
      <div style={{ marginTop: "10px" }}>
        <input
          type="range"
          min="0"
          max={videoState.duration || 0}
          value={videoState.currentTime}
          onChange={handleSeek}
          style={{ width: "100%" }}
        />
        <div style={{ display: "flex", justifyContent: "space-between", fontSize: "12px" }}>
          <span>{videoState.currentTime.toFixed(2)}s</span>
          <span>{videoState.duration.toFixed(2)}s</span>
        </div>
      </div>
 
      {/* Controls */}
      <div style={{ marginTop: "10px", display: "flex", gap: "10px", alignItems: "center" }}>
        <button onClick={() => videoControls.rewind(10)}>⏪ 10s</button>
        <button onClick={videoState.isPaused ? videoControls.play : videoControls.pause}>
          {videoState.isPaused ? "▶️" : "⏸️"}
        </button>
        <button onClick={() => videoControls.fastForward(10)}>⏩ 10s</button>
        <button onClick={videoControls.toggleMute}>
          {videoState.isMuted ? "🔇" : "🔊"}
        </button>
        <input
          type="range"
          min="0"
          max="1"
          step="0.1"
          value={videoState.volume}
          onChange={handleVolumeChange}
          style={{ width: "100px" }}
        />
        <span>{(videoState.volume * 100).toFixed(0)}%</span>
      </div>
    </div>
  );
}

Video playlist with multiple videos

import { useVideo } from "rooks";
import React, { useState } from "react";
 
export default function App() {
  const [videoRef, videoState, videoControls] = useVideo();
  const [currentVideoIndex, setCurrentVideoIndex] = useState(0);
 
  const videos = [
    {
      src: "https://www.w3schools.com/html/mov_bbb.mp4",
      title: "Big Buck Bunny",
    },
    {
      src: "https://www.w3schools.com/html/movie.mp4",
      title: "Sample Video 2",
    },
  ];
 
  const nextVideo = () => {
    if (currentVideoIndex < videos.length - 1) {
      setCurrentVideoIndex(currentVideoIndex + 1);
    }
  };
 
  const prevVideo = () => {
    if (currentVideoIndex > 0) {
      setCurrentVideoIndex(currentVideoIndex - 1);
    }
  };
 
  return (
    <div style={{ padding: "20px", maxWidth: "600px" }}>
      <h1>Video Playlist</h1>
      <h2>{videos[currentVideoIndex].title}</h2>
      
      <video
        ref={videoRef}
        width="100%"
        height="300"
        src={videos[currentVideoIndex].src}
        controls={false}
        key={currentVideoIndex} // Force re-render when video changes
      />
      
      <div style={{ marginTop: "10px" }}>
        <p>
          Video {currentVideoIndex + 1} of {videos.length}
        </p>
        <p>Progress: {videoState.currentTime.toFixed(2)}s / {videoState.duration.toFixed(2)}s</p>
      </div>
 
      <div style={{ marginTop: "10px", display: "flex", gap: "10px", flexWrap: "wrap" }}>
        <button onClick={prevVideo} disabled={currentVideoIndex === 0}>
          Previous
        </button>
        <button onClick={videoState.isPaused ? videoControls.play : videoControls.pause}>
          {videoState.isPaused ? "Play" : "Pause"}
        </button>
        <button onClick={nextVideo} disabled={currentVideoIndex === videos.length - 1}>
          Next
        </button>
        <button onClick={() => videoControls.fastForward(30)}>Skip 30s</button>
        <button onClick={videoControls.toggleMute}>
          {videoState.isMuted ? "Unmute" : "Mute"}
        </button>
      </div>
    </div>
  );
}

Arguments

The useVideo hook takes no arguments.

Return Value

Returns an array with three elements:

[
  RefObject<HTMLVideoElement | null>,
  VideoState,
  VideoControls
]

VideoState

PropertyTypeDescription
currentTimenumberCurrent playback time in seconds
durationnumberTotal duration of the video in seconds
isPausedbooleanWhether the video is currently paused
isMutedbooleanWhether the video is currently muted
volumenumberCurrent volume level (0.0 to 1.0)

VideoControls

MethodTypeDescription
play() => voidStart playing the video
pause() => voidPause the video
toggleMute() => voidToggle mute state
setVolume(volume: number) => voidSet volume level (0.0 to 1.0)
setCurrentTime(time: number) => voidSet current playback time in seconds
fastForward(seconds: number) => voidFast forward by specified seconds
rewind(seconds: number) => voidRewind by specified seconds
toggleFullScreen() => voidToggle fullscreen mode

VideoRef

The first element in the return array is a React ref that should be attached to the video element you want to control. This ref provides access to the underlying HTMLVideoElement.


On this page