ReactJS

 

Revamping Media Playback: Building Versatile Video Player Hooks with ReactJS’s useVideo

ReactJS is a powerful JavaScript library designed to make building user interfaces seamless, efficient, and scalable. It empowers developers to create single-page applications and mobile apps with reusable UI components. One of its most potent features is hooks. 

Revamping Media Playback: Building Versatile Video Player Hooks with ReactJS's useVideo

React Hooks enable function components to use state and other React features without having to write a class. They’re highly flexible and intuitive, allowing developers to encapsulate complex logic inside a single hook. Today, we’ll explore how to create a custom hook for a video player. This hook, which we’ll call `useVideo`, will allow us to control video playback and handle the video’s state more effectively. 

Getting Started

Before we get into creating our `useVideo` hook, ensure you have the following prerequisites installed:

  1. Node.js and npm
  2. ReactJS (version 16.8 or later)
  3. Your favorite text editor (VSCode, Atom, Sublime, etc.)

We’ll start by creating a new React project using the Create React App.

npx create-react-app video-player-hooks

Now, navigate into the project folder.

We’ll be working primarily within the `src` directory.

Building the useVideo Hook

First, let’s create a new folder named `hooks` within the `src` directory, where we’ll keep our custom hooks. Inside this folder, create a new file named `useVideo.js`. 

Our `useVideo` hook will allow us to control play/pause status, current time, volume, playback rate, and more. To start, we’ll define the initial state of our video:

```jsx
import { useState, useEffect, useRef } from 'react';

const useVideo = (video) => {
    const [status, setStatus] = useState('paused');
    const [currentTime, setCurrentTime] = useState(0);
    const [volume, setVolume] = useState(1);
    const [playbackRate, setPlaybackRate] = useState(1);
    const videoRef = useRef(null);

    // Rest of the code goes here
}
```

Here, `useState` sets up our state variables, and `useRef` holds a reference to our video element.

Next, we’ll use `useEffect` to set the source of our video and set up event listeners when the component mounts.

```jsx
useEffect(() => {
    videoRef.current.src = video;

    videoRef.current.addEventListener('play', handlePlay);
    videoRef.current.addEventListener('pause', handlePause);
    videoRef.current.addEventListener('timeupdate', handleTimeUpdate);

    return () => {
        videoRef.current.removeEventListener('play', handlePlay);
        videoRef.current.removeEventListener('pause', handlePause);
        videoRef.current.removeEventListener('timeupdate', handleTimeUpdate);
    };
},
},
);
```

In the above code, we’re adding event listeners for the ‘play’, ‘pause’, and ‘timeupdate’ events. We also make sure to remove these listeners when the component unmounts.

Now, let’s define the event handler functions:

```jsx
const handlePlay = () => setStatus('playing');
const handlePause = () => setStatus('paused');
const handleTimeUpdate = () => setCurrentTime(videoRef.current.currentTime);
```

These handlers update our state variables accordingly when the respective events are fired.

To allow the user to control the video, we’ll create a few more functions:

```jsx
const play = () => videoRef.current.play();
const pause = () => videoRef.current.pause();
const seek = (time) => (videoRef.current.currentTime = time);
const changeVolume = (newVolume) => (videoRef.current.volume =

 newVolume);
const changePlaybackRate = (rate) => (videoRef.current.playbackRate = rate);
```

Finally, our hook will return an object containing all the state variables and functions:

```jsx
return {
    status,
    currentTime,
    volume,
    playbackRate,
    videoRef,
    play,
    pause,
    seek,
    changeVolume,
    changePlaybackRate
};
```

This completes the `useVideo` hook. Here’s the complete code for reference:

```jsx
import { useState, useEffect, useRef } from 'react';

const useVideo = (video) => {
    const [status, setStatus] = useState('paused');
    const [currentTime, setCurrentTime] = useState(0);
    const [volume, setVolume] = useState(1);
    const [playbackRate, setPlaybackRate] = useState(1);
    const videoRef = useRef(null);

    useEffect(() => {
        videoRef.current.src = video;

        videoRef.current.addEventListener('play', handlePlay);
        videoRef.current.addEventListener('pause', handlePause);
        videoRef.current.addEventListener('timeupdate', handleTimeUpdate);

        return () => {
            videoRef.current.removeEventListener('play', handlePlay);
            videoRef.current.removeEventListener('pause', handlePause);
            videoRef.current.removeEventListener('timeupdate', handleTimeUpdate);
        };
    },
);

    const handlePlay = () => setStatus('playing');
    const handlePause = () => setStatus('paused');
    const handleTimeUpdate = () => setCurrentTime(videoRef.current.currentTime);

    const play = () => videoRef.current.play();
    const pause = () => videoRef.current.pause();
    const seek = (time) => (videoRef.current.currentTime = time);
    const changeVolume = (newVolume) => (videoRef.current.volume = newVolume);
    const changePlaybackRate = (rate) => (videoRef.current.playbackRate = rate);

    return {
        status,
        currentTime,
        volume,
        playbackRate,
        videoRef,
        play,
        pause,
        seek,
        changeVolume,
        changePlaybackRate
    };
}

export default useVideo;
```

Using the useVideo Hook

With our `useVideo` hook ready, let’s see how to use it in a functional component.

Create a new `VideoPlayer` component in your `components` folder:

```jsx
import React from 'react';
import useVideo from '../hooks/useVideo';

const VideoPlayer = ({ src }) => {
    const {
        status,
        currentTime,
        volume,
        playbackRate,
        videoRef,
        play,
        pause,
        seek,
        changeVolume,
        changePlaybackRate
    } = useVideo(src);

    return (
        <div>
            <video ref={videoRef} />
            {/* Controls and other UI components go here */}
        </div>
    );
};

export default VideoPlayer;
```

In the above example, we pass the `src` prop to our `useVideo` hook and get back an object containing the state and control functions. We can now use these to build our video player interface.

Conclusion

React hooks open the door to effective abstraction and code reusability. Building custom hooks, such as `useVideo`, simplifies the process of managing video state and control. By encapsulating all the complex logic inside the hook, we can now quickly add video players to our React applications with little to no redundancy.

Remember, hooks are just JavaScript functions, meaning you can always adapt and enhance them to better suit your needs.

Happy coding!

Previously at
Flag Argentina
Argentina
time icon
GMT-3
Seasoned Software Engineer specializing in React.js development. Over 5 years of experience crafting dynamic web solutions and collaborating with cross-functional teams.