How I build a YouTube Video Player with ReactJS: Build the Seekbar control
Tags: react, opensource, javascript, tutorial
Published: 2024-01-17 10:51:30

## Introduction

In the previous blog, we discussed the volume slider and how it utilizes the slider component. To dive deeper we also built the slider component in that blog. I recommend you all give it a [read](https://dev.to/keyurparalkar/how-i-build-a-youtube-video-player-with-reactjs-building-the-volume-control-4jli). 

In this blog, we will be building the Seekbar of the video using the Slider component. 

So, without further ado, let's get started!

<aside>
💡 **NOTE:** The implementation of chapter fill css-variable was inspired from the https://www.vidstack.io/

</aside>

## Prerequisites

I would highly recommend going through the below topics before diving into this blog post:

- [React’s useEffect hook](https://react.dev/reference/react/useEffect)
- [Typescript](https://www.typescriptlang.org/)
- [styled-components](https://styled-components.com/)

## What is a seekbar component?

![seekbar](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ve50t8bthwmu7tcmprht.png)

A seek bar is a component that represents the video’s overall progress. It represents how much time that has elpased of the video. It can also be used to go forward or backward in the video by clicking or dragging the slider. It can also be used to preview the video’s current frame.

All these feature of the seek bar we will be implementing in this and in the subsequent blog posts.

## Building the basic structure of the Seekbar Control component

In this section, we will be building the Seekbar component’s basic structure. So first let us start by creating the component file at this location: `src/components/Seekbar.tsx`. Next, copy-paste the below code:

{% embed https://gist.github.com/keyurparalkar/b55cfc088cd9babd6fa1ddd3895d87ee/fc6ddb5d38e9a99ad460b6f9533d908e3ffc3408 %}

Here we build the very basic component structure. We will take a look at the details in the next section. Now, import this component inside the `src/components/ControlToolbar.tsx`:

{% embed https://gist.github.com/keyurparalkar/165e946744d6961742a8d61387a6f367 %}

So the basic functionality of defining and calling the component is done. Now, let us dive deeper into the implementation of this component.

## Implementing the Seekbar control component

Implementation is straightforward, we build this component below step-by-step:

* First, import the `slider` component and add these basic props:
    {% embed https://gist.github.com/keyurparalkar/b55cfc088cd9babd6fa1ddd3895d87ee/1a0d3feb998aa38d49debbcec5dd3d40c5290274 %}
    
    This will create a basic slider with a width of `780px` and with the `$fillColor` of `red`. Here is what it will look like:

    ![Seekbar with fill](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2a855abwoeikj1egwnjf.png)

* Since this component aims to seek through the video. So for that, we need to create new properties in the global state: `currentTime`, `totalDuration`, `isSeeking` and `hasVideoLoaded`. I won’t go into much detail on how to add these into the global state. For that you can follow this blog [post](https://dev.to/keyurparalkar/building-with-react-js-create-your-own-youtube-video-player-starting-with-basics-1lpp). Will be giving a small summary of changes quickly:
    - Update the interface of the Global state along with the initial state:
    {% embed https://gist.github.com/keyurparalkar/d90a28d09f3d7581e7349a820c12e78a %}
    - Update actions:
    {% embed https://gist.github.com/keyurparalkar/f57fce868ec89e340aad897af5c4f56e %}
    - Update reducer:
    {% embed https://gist.github.com/keyurparalkar/24a818982be8b0560600184f66777fd8 %}
    - In the `src/components/Video.tsx` file we add a `useEffect` such that whenever the video is loaded we initialize the `totalDuration` and `hasVideoLoaded` like below by dispatching the `HAS_VIDEO_LOADED` action:
    {% embed https://gist.github.com/keyurparalkar/b2704723970ed8a0ed694cd1d67ee809/abb718937dd875f14dbc8476ce49028395427219 %}
        - Next, we also need to add the following `useEffect` to update the duration of the video when the `currentTime` changes while dragging of the slider:
        {% embed https://gist.github.com/keyurparalkar/b2704723970ed8a0ed694cd1d67ee809/9848793ef67fb95a72ea83c021c1a9511359265e %}
        - Lastly, to make the above effect run we update the video duration on each second by passing on the `handleTimeUpdate` to the `onTimeUpdate` event of the video element:
        {% embed https://gist.github.com/keyurparalkar/b2704723970ed8a0ed694cd1d67ee809/2a73441e61efe8acdc47e0972ca64ea674bca4f5 %}

* Once we have our global store setup we now start implementing the `Seekbar` component. We first implement the mechanism of updating the slider on the playback of the video such that the slider gets updated every second. To do that we add the following `useEffect`:
{% embed https://gist.github.com/keyurparalkar/b55cfc088cd9babd6fa1ddd3895d87ee/31b58ab8c460575fd32b0a09b70dbe9b87619e43 %}

    To update the slider on every second we need to update the `--slider-fill` variable on each second. To achieve that, inside the `useEffect` we calculate the fill percentage in `newPosPercentage` with the help of `currentTime` and `totalDuration`. Once we get it, we update the `--slider-fill` with the `updateSliderFill` function.

    
    If you are not getting the above concept I highly recommend you to go through the [previous blog post for slider’s implementation](https://dev.to/keyurparalkar/how-i-build-a-youtube-video-player-with-reactjs-building-the-volume-control-4jli).

    
    Here if you see we also make use of the `isSeeking` state. This is because, we don’t want the above mechanism to get triggered while we are dragging the slider.

* Next, to add the logic of seeking the video on click of the slider we add an event handler called: `onPositionChangeByClick` and pass it on to the `Slider` component:
    
    {% embed https://gist.github.com/keyurparalkar/b55cfc088cd9babd6fa1ddd3895d87ee/e5f9eb37a6dce862fbccca696844869cb23fabc7 %}
    The above event handler will receive the `currentPercentage` of the slider i.e. the current value. From that we calculate the new current duration of the video. Then, we dispatch the action: `UPDATE_VIDEO_CURRENT_TIME` to update the `currentTime`.
    
    We also make use of the `UPDATE_SEEKING` action that updates the `isSeeking` state. We first update it to `true` in the event handler and then to `false` whenever the mouse up handler is fired. We do this so that we can distinguish when the slider is getting dragging for seeking or not. This helps us distinguish in lot many places.

* Next, to handle the scenario where we want to seek the video on drag we add the `onPositionChangeByDrag` event handler for the `onDrag` event of the `Slider` component:
    {% embed https://gist.github.com/keyurparalkar/b55cfc088cd9babd6fa1ddd3895d87ee/5ef5cea67e6298083a1a66914dd02dbd3162b708 %}    

Our final component updates will look like below:
{% embed https://gist.github.com/keyurparalkar/b55cfc088cd9babd6fa1ddd3895d87ee/3200ae20d7810293bea78af6429acc03b2d4eab3 %}

Here is how are complete change will look like:

![final-gif](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mas8s27yhff6wump6spg.gif)



## Summary

To Summarize we implemented the following things in this post:

- We saw the global state changes that were required.
- We implemented the seekbar that wired up with video.
- We made the seekbar intectative by adding event handlers for drag and click events.
- We also implemented the logic to update the seekbar on video playback.

In the next blog post of this series, we are going to talk about building an exciting component called `FrameTooltip` component that shows the preview of each video frame on hover of seekbar, so stay tuned guys !!!

The entire code for this tutorial can be found [here](https://github.com/keyurparalkar/react-youtube-player-clone).

Thank you for reading!

Follow me on [twitter](https://twitter.com/keurplkar), [github](http://github.com/keyurparalkar), and [linkedIn](https://www.linkedin.com/in/keyur-paralkar-494415107/).