Front-End Development VideoJS and React: A Perfect Match for Modern Video Players React Optimization 101: Tips and Tricks Integrating Cloudinary with Astro Building an Image Upload Feature with JavaScript Mastering Image Alignment: Centering Images with HTML & CSS Adding Video to Your React Native App with react-native-video HTML Image Slider: Do It Yourself and 1-Step Image Gallery Widget How to Effectively Manage Digital Assets in a PHP Image Gallery Introducing Angular Image Editor: Your New Editing Too Mastering Javascript Image Annotation Mastering JavaScript Image Popup Python Video Player: 3 Free Options and a Quick Tutorial Image Recognition Machine Learning: Use Cases and Common Algorithms HTML/CSS: How to Center Images Vertically and Horizontally How to Create an Image Map Understand CSS Background Position with 4 Simple Examples Java for Image Processing: 4 Libraries You Should Know Python Video Processing: 6 Useful Libraries and a Quick Tutorial Blur Image CSS: Two Ways to Blur Images for Gorgeous Effects Designing a Video Flipping App for Android Build an App for Embedding Video Watermarks on Android Devices Change Image on Hover with HTML and CSS How to Align Images with CSS Full Page Background Image with CSS: Tutorial and 5 Automation Tips Using CSS to Scale Page Elements and a Better Way to Scale Your Images CSS Background Image: Quick Tutorial and 3 Automation Tips Featured Image: Best Practices to Feature Images on Your Website Image Gallery Websites: Tips and Tricks for a Stunning Image Gallery 6 Ways to Stretch a Background Image with CSS Auto Cropping for Images and Video: Features & Best Practices FLAC vs. WAV: 4 Key Differences and How to Choose Converting Audio to Video: A Practical Guide FLAC vs. AIFF: 5 Key Differences and How to Choose FLAC vs. MQA: 5 Key Differences and How to Choose Converting WAV Files To OGG The Ultimate Guide On Converting OGG Files To WAV Sound Choices: FLAC vs. MP3 AAC vs MP3 – The Future of Audio Files All about AIFF and how it compares to WAV and MP3 Integrating Cloudinary with Netlify Integrating Cloudinary with Svelte and SvelteKit Integrating Cloudinary with Nuxt Integrating Cloudinary with Gatsby File Upload as a Service: How It Works and 5 Leading Solutions Native Mobile App Development Creative Uses for CSS Inner Border and 3 Ways to Set a Border Integrating Cloudinary with Next.js Front-End Development: The Complete Guide

VideoJS and React: A Perfect Match for Modern Video Players

header image

Videos are found everywhere on the internet today, from social media apps, to learning platforms and media websites. To create a smooth watching experience for your users, you need tools that make managing and delivering videos easy and efficient. That’s where Video.js comes in. Video.js is an open-source web video player that simplifies creating video with HTML5. Video.js is packed with features, plugins, and customization options that help developers add and control video players on websites.

React is a JavaScript front-end library for building user interfaces in web applications. Its component-based structure works perfectly with Video.js, making it simple to create and manage video players in web applications. In this article, we’ll go over what Video.js is, how it works, and how to leverage its powerful capabilities to build a modern, user-friendly video player in your applications. Let’s get started!

In this article:

Why Use Video.js in Modern Web Development?

The native HTML5 video element lacks features required by many modern applications and websites. As an alternative to these built-in features, Video.js is an open-source HTML5 video player framework that provides a consistent and customizable video playback experience across diverse web browsers and devices. It offers a comprehensive set of features, including customizable UI, cross-browser compatibility, an extensive plugin ecosystem, live streaming capabilities, and more.

Majority of web apps today need advanced features that raw HTML5 doesn’t offer, like:

  • Cross-platform compatibility: Some advanced video players settings are not supported by certain browsers, which can lead to inconsistent user experiences. Video.js solves this issue by ensuring that the video player works seamlessly across the majority of web browsers. It also has support for desktop applications, which further expands its reusability.
  • Customizable interfaces: Video.js allows you to change how the video player looks and feels by providing your own CSS styles.
  • Support for multiple formats: Playing different video file types is easy using Video.js is easy. It allows you to play “traditional” file formats such as MP4 and WebM, but also supports adaptive streaming formats such as HLS streaming and DASH, with an additional special UI for live streams.
  • Extensibility with plugins: Some apps need extra features that the HTML video element can’t provide. Tools like Video.js allow you to add plugins to include those advanced capabilities to meet your specific project requirements.

What is React (And Why Use It with Video.js)?

React is a front-end JavaScript library created by Facebook for building single-page and complex web applications. React simplifies creating web apps by providing a lot of useful performance improvement capabilities, like a simplified process for structuring apps using components and state management for complex apps and an improved developer experience.

These capabilities have made React a go-to choice for developers for creating web applications. In a recent survey conducted by Stack Overflow, React tops the list of the web frameworks and technologies developers have worked with.

Combining Video.js with React allows you to create a highly customizable and efficient video player that fits seamlessly into a React-based user interface, ensuring smooth integration of video elements with the overall app, while also leveraging React’s state management and reusable components.

How to Implement Video.js in a React Project

In this section, we’ll walk you through the steps to implement Video.js in a React app. We assume you have some basic experience with JavaScript and you are comfortable writing React code.

Set up a React application

To get started, create a new React application. For this tutorial, we’ll be using Vite to build our scaffolding, which you can follow along with this guide. However, you can build your own project however you like.

Once you finish, your project directory should look something like this:

image_1

Install Video.js

Next, install Video.js. To do so, open a terminal window in the project root directory and run the following code:

npm install --save-dev video.js

Then start the application server:

npm run dev

Create a video component

We will create a dedicated component which will contain the code to initialize and configure the video player. Create a file named VideoJS.jsx in the src folder and add the following code to it:

import React from 'react';
import videojs from 'video.js';
import 'video.js/dist/video-js.css';

export const VideoJS = (props) => {
  const videoRef = React.useRef(null);
  const playerRef = React.useRef(null);
  const { options, onReady } = props;

  React.useEffect(() => {
    if (!playerRef.current) {
      const videoElement = document.createElement('video-js');
      videoElement.classList.add('vjs-big-play-centered');
      videoRef.current.appendChild(videoElement);

      const player = (playerRef.current = videojs(videoElement, options, () => {
        videojs.log('player is ready');
        if (onReady) {
          onReady(player);
        }
      }));
    } else {
      const player = playerRef.current;
      player.autoplay(options.autoplay);
      player.src(options.sources);
    }
  }, [options]);

  React.useEffect(() => {
    const player = playerRef.current;
    // Clean up function to dispose the player after the component unmounts
    return () => {
      if (player && !player.isDisposed()) {
        player.dispose();
        playerRef.current = null;
      }
    };
  }, []);

  return (
    <div className='video-player' data-vjs-player>
      <div ref={videoRef} />
    </div>
  );
};

export default VideoJS;

Let’s understand what going on in the code above:

  • videoRef stores a reference to the underlying <video> DOM element.
  • playerRef stores the initialized Video.js player instance to ensure there’s only one instance.
  • The import 'video.js/dist/video-js.css'; line imports the default Video.js CSS styles for the look of the video player
  • The first useEffect function initializes the Video.js player when the component mounts if it hasn’t been created, adding the video element and applying the provided options
  • Next, we defined a second useEffect cleanup function to dispose of the Video.js instance when the component unmounts (to avoid memory leaks or performance issues).

Next, replace the content of App.jsx with the following:

import React from 'react';
import VideoJS from './VideoJS';
import './App.css';

const App = () => {
  const playerRef = React.useRef(null);

  const videoJsOptions = {
    autoplay: true,
    controls: true,
    responsive: true,
    fluid: true,
    sources: [
      {
        src: 'video.mp4',
        type: 'video/mp4',
      },
    ],
  };

  const handlePlayerReady = (player) => {
    playerRef.current = player;

    player.on('waiting', () => {
      console.log('Player is waiting');
    });

    player.on('dispose', () => {
      console.log('Player will dispose');
    });
  };

  return (
    <div className='video-wrapper'>
      <h1>React and Video.js Example</h1>
      <VideoJS options={videoJsOptions} onReady={handlePlayerReady} />
    </div>
  );
};

export default App;

The above component sets up a Video.js player with a custom configuration using the VideoJS component we created earlier. It also defines videoJsOptions to configure the player with properties like autoplay, controls, responsiveness, and a video source. The handlePlayerReady function manages player events (waiting and dispose) and stores the player instance in a ref for further interaction.

The video used in the code can be downloaded from here.

Then, for the page styling, replace the content of App.css with the following:

body {
  margin: 0;
  padding: 0;
  background-color: #ffffff;
  font-family: Arial, sans-serif;
}

#root {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  box-sizing: border-box;
}

h1 {
  font-size: 24px;
  color: #333333;
  text-align: center;
  margin-bottom: 20px;
}

.video-wrapper {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  margin: auto;
}

.video-player {
  width: 800px;
}

Then, in main.js, replace the code with this:

import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.jsx'

createRoot(document.getElementById('root')).render(
  <StrictMode>
    <App />
  </StrictMode>,
)

Here’s what the app should look like so far:

image 2

Customize the video player

Video.js provides several ways to customize the look and functionality of the video player. To change the look of the video player, for example, we can create a skin which overrides the default styles.

We can add a new class by modifying the options or using JavaScript to add the class. For example, to create a Netflix-styled application, let’s create a CSS file with the custom styles:

/* Base styling for the Video.js player */
.video-js {
    font-size: 16px; 
    color: #cacaca;
  }


  .vjs-default-skin .vjs-big-play-button {
    font-size: 4em;
    width: 1.5em;
    height: 1.5em;
    line-height: 1.5em;
    border-radius: 50%;
    background: transparent;
    position: absolute;
    left: 50%;
    top: 40%;
    transform: translate(-50%, -50%);
    display: none; 
  }


  /* Control bar background */
  .video-js .vjs-control-bar,
  .video-js .vjs-big-play-button {
    background-color: rgba(38, 38, 38, 0.9);
    border-radius: 0.5em;
  }


  .video-js .vjs-control {
    border-right: 1px solid #323232;
  }


  .video-js .vjs-play-control:before {
    content: '\25BA';
    font-size: 1.2em;
  }


  .video-js .vjs-playing .vjs-play-control:before {
    content: '\23F8'; 
  }


  /* Fullscreen control */
  .video-js .vjs-fullscreen-control:before {
    content: '\26F6';
  }


  /* Volume control */
  .video-js .vjs-volume-menu-button:before {
    content: '\1F50A'; 
  }


  /* Progress bar styles */
  .video-js .vjs-progress-control {
    height: 0.9em;
    background-color: rgba(38, 38, 38, 0.9);
    border-radius: 1em;
  }


  .video-js .vjs-play-progress {
    background: #b7090b;
    border-radius: 1em;
  }


  .video-js .vjs-load-progress {
    background: rgba(38, 38, 38, 0.5);
  }


  /* Slider handle customization */
  .video-js .vjs-play-progress:before {
    content: '';
    position: absolute;
    width: 1em;
    height: 1em;
    border-radius: 50%;
    background: radial-gradient(circle, #b7090b 33%, #830607);
    transform: translate(-50%, -50%);
    top: 50%;
    left: 100%;
    box-shadow: 0 0 2px #000;
  }


  .video-js .vjs-play-progress:hover:before {
    width: 1.2em;
    height: 1.2em;
  }


  .video-js .vjs-time-tooltip {
    background: #cacaca !important;
    color: #b7090b !important;
    border-radius: 3px;
  }


  .vjs-loading-spinner {
    background: url('https://assets.nflxext.com/en_us/pages/wiplayer/site-spinner.png') no-repeat center center;
    background-size: 50%;
    border: none;
  }


  .video-js:hover .vjs-control-bar {
    bottom: 2em;
    transition: bottom 0.3s ease-in-out;
  }


  .video-js.vjs-fullscreen .vjs-control-bar {
    bottom: 3em;
  }

Then import the custom styles in the VideoJS.jsx component:

import './videojs-netflix.css';

Here’s what the player looks like:

image 3

Advanced Use Cases and Plugins with Video.js and React

Video.js’s extendability enables developers to create highly customized video players that are tailored to their specific project requirements. There are several plugins available to extend the capabilities of Video.js. Some notable plugins include:

  • videojs-vjsdownload: Provides a functionality to add a button to download the video inside the player.
  • videojs-record: Enables recording of audio, video, and image files.
  • videojs-ass: Adds Advanced SubStation Alpha (ASS) subtitles support to Video.js using the libjass library.
  • videojs-analytics: This plugin allows you to track Google Analytics events from the video player.
  • videojs-dynamic-watermark: Lets you display text watermark over the Video.js player and updates the position dynamically.
  • videojs-landscape-fullscreen: Allows you to rotate to landscape mode to enter full-screen and always enter full-screen in landscape mode even if the device is in portrait mode.

Using Cloudinary with Video.js and React

Cloudinary is a cloud-based media management platform that integrates seamlessly with both Video.js and React. Through Cloudinary’s API and SDKs, you can use the video player within your React applications to manage video assets dynamically, including real-time encoding and responsive delivery.

The Cloudinary Video Player serves as a video delivery tool and a platform for hosting and optimizing video files, providing rapid and reliable distribution through a content delivery network. What’s more, Cloudinary offers the ability to transform videos in real-time, like resizing or changing the format, as they are delivered to users.

For advanced functionalities like streaming, automatic video quality selection, Cloudinary offers support for HLS and DASH streaming, which makes working with videos easier and more efficient. You can learn more about the video player here through the various demos that have been created.

main banner

Wrapping Up

Using Video.js with React is a great way to build video players that are both powerful and easy to customize. Video.js offers many advanced features, while React’s component-based structure makes creating and managing video players simpler. Combining the two together makes it easier to deliver high-quality, interactive video content to users. Integrating Cloudinary can help optimize video delivery and simplify media management, improving performance and scalability in modern applications.

For your next React project, ‌sign up today to use Cloudinary’s powerful media management tools coupled with Video.js to provide a rich video experience for your users!

QUICK TIPS
Colby Fayock
Cloudinary Logo Colby Fayock

In my experience, here are tips to enhance your use of Video.js and React for building modern, feature-rich video players:

  1. Use lazy loading for video components
    Implement lazy loading to defer video initialization until the component is visible on the user’s viewport. This reduces the page’s initial load time and improves overall performance.
  2. Preload video metadata for better user experience
    Set the preload attribute to "metadata" in your video player options when using large video files. This allows the player to load essential details (like duration) without downloading the entire video.
  3. Customize event listeners for analytics
    Extend your onReady handler to capture detailed analytics. Track events like play, pause, and seek to gain insights into user engagement with the video content. Use tools like Google Analytics or custom endpoints for data collection.
  4. Incorporate Picture-in-Picture (PiP) mode
    Enable PiP mode in Video.js to let users watch videos in a floating window while interacting with other parts of your app. Use plugins like videojs-pip to easily add this functionality.
  5. Leverage HLS and DASH for adaptive streaming
    Use the Video.js HLS or DASH plugins for delivering adaptive bitrate streams. This ensures smooth playback across varying network conditions and optimizes video quality for the viewer.
  6. Add subtitles and closed captions
    Use Video.js’s built-in support for WebVTT and plugins like videojs-ass to include subtitles and captions. Allow users to toggle these options for accessibility and localization.
  7. Implement custom control components
    Use React to design bespoke controls like branded play buttons or interactive overlays. Replace the default Video.js controls with your React-based components for a fully customized player UI.
  8. Streamline responsiveness with the fluid option
    Set the fluid option to true in your Video.js configuration to create responsive video players that adapt seamlessly to any screen size or orientation.
  9. Use dynamic loading for plugins
    Dynamically load only the Video.js plugins needed for specific scenarios to reduce the bundle size and improve application performance. Conditional imports in React can help manage this effectively.
  10. Automate video quality and format selection
    Integrate Cloudinary to automate video quality adjustments based on user devices and network speed. This improves loading times and playback quality, especially for users with limited bandwidth.
Last updated: Dec 4, 2024