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?
- What is React (And Why Use It with Video.js)?
- How to Implement Video.js in a React Project
- Advanced Use Cases and Plugins with Video.js and React
- Using Cloudinary with Video.js and React
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:
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:
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:
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.
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!