Video.js Guides
These guides cover a range of topics for users of Video.js
React and Video.js
Table of Contents
These are several React and Video.js player implementations and examples.
Don't forget to include the Video.js CSS, located at video.js/dist/video-js.css
!
React Functional Component and useEffect
Example
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(() => {
// Make sure Video.js player is only initialized once
if (!playerRef.current) {
// The Video.js player needs to be _inside_ the component el for React 18 Strict Mode.
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');
onReady && onReady(player);
});
// You could update an existing player in the `else` block here
// on prop change, for example:
} else {
const player = playerRef.current;
player.autoplay(options.autoplay);
player.src(options.sources);
}
}, [options, videoRef]);
// Dispose the Video.js player when the functional component unmounts
React.useEffect(() => {
const player = playerRef.current;
return () => {
if (player && !player.isDisposed()) {
player.dispose();
playerRef.current = null;
}
};
}, [playerRef]);
return (
<div data-vjs-player>
<div ref={videoRef} />
</div>
);
}
export default VideoJS;
Finally, use the component like this (see Video.js Options Reference):
import React from 'react';
// This imports the functional component from the previous sample.
import VideoJS from './VideoJS'
const App = () => {
const playerRef = React.useRef(null);
const videoJsOptions = {
autoplay: true,
controls: true,
responsive: true,
fluid: true,
sources: [{
src: '/path/to/video.mp4',
type: 'video/mp4'
}]
};
const handlePlayerReady = (player) => {
playerRef.current = player;
// You can handle player events here, for example:
player.on('waiting', () => {
videojs.log('player is waiting');
});
player.on('dispose', () => {
videojs.log('player will dispose');
});
};
return (
<>
<div>Rest of app here</div>
<VideoJS options={videoJsOptions} onReady={handlePlayerReady} />
<div>Rest of app here</div>
</>
);
}
React Class Component Example
This example component instantiates the Video.js player on componentDidMount
and destroys it on componentWillUnmount
.
import React from 'react';
import videojs from 'video.js';
import 'video.js/dist/video-js.css';
export default class VideoPlayer extends React.Component {
// Instantiate a Video.js player when the component mounts
componentDidMount() {
this.player = videojs(this.videoNode, this.props, () => {
videojs.log('onPlayerReady', this);
});
}
// Dispose the player when the component will unmount
componentWillUnmount() {
if (this.player) {
this.player.dispose();
}
}
// Wrap the player in a `div` with a `data-vjs-player` attribute, so Video.js
// won't create additional wrapper in the DOM.
//
// See: https://github.com/videojs/video.js/pull/3856
render() {
return (
<div data-vjs-player>
<video ref={node => this.videoNode = node} className="video-js"></video>
</div>
);
}
}
Finally, use the component like this (see Video.js Options Reference):
const videoJsOptions = {
autoplay: true,
controls: true,
sources: [{
src: '/path/to/video.mp4',
type: 'video/mp4'
}]
}
return <VideoPlayer {...videoJsOptions} />
Using a React Component within a Video.js Component
This example demonstrates using a React component within a Video.js component inside a Video.js player. Through this approach, developers can manage their custom Video.js components through React.
First, a normal React component is created:
import {Component} from 'react';
export default class ExampleReactComponent extends Component {
render() {
return (
<div>{this.props.text}</div>
);
}
};
Within this component, the vjsBridgeComponent
is available on its props
. Through this object, methods of the vjsBridgeComponent
are available.
The Video.js player can be referenced within this React component via the same means:
const player = this.props.vjsBridgeComponent.player();
Next, a Video.js component is created.
This component renders the React component into itself. Basically, the Video.js component is acting as a bridge between the Video.js player and the React component:
import ExampleReactComponent from './example-react-component';
import ReactDOM from 'react-dom';
import videojs from 'video.js';
const VjsComponent = videojs.getComponent('Component');
class ExampleVjsBridgeComponent extends VjsComponent {
constructor(player, options) {
super(player, options);
// Bind the current class context to the mountReactComponent method
this.mountReactComponent = this.mountReactComponent.bind(this);
// When player is ready, call method to mount the React component
player.ready(() => this.mountReactComponent());
// Remove the React root when this component is destroyed
this.on('dispose', () => ReactDOM.unmountComponentAtNode(this.el()));
}
// This method renders the ExampleReactComponent into the DOM element of
// the Video.js component, `this.el()`.
mountReactComponent() {
ReactDOM.render(
<ExampleReactComponent vjsBridgeComponent={this} text='Example React Component' />,
this.el()
);
}
}
// Make sure to register the Video.js component so Video.js knows it exists
videojs.registerComponent('exampleVjsBridgeComponent', ExampleVjsBridgeComponent);
export default ExampleVjsBridgeComponent;
Finally, the Video.js bridge component can be added to the player like so:
// ...
// Instantiate a Video.js player when the component mounts
componentDidMount() {
this.player = videojs(this.videoNode, this.props, () => {
videojs.log('onPlayerReady', this);
});
// Add the ExampleVjsBridgeComponent as a child of the player (or
// of another component within the player, such as the control bar).
//
// You can pass options to your bridge component using the second argument
// to this method.
this.player.addChild('exampleVjsBridgeComponent', {});
}
// ...