Skip to main content
Not every player needs to support every use case. To address this, Video.js has a concept of features — self-contained units of player functionality. Each feature adds state properties and actions to the player. For example, playback adds paused and play(), volume adds volume and setVolume(), and so on.

Using features

Feature bundles and presets

You probably don’t want to hand-pick every feature your player needs. A feature bundle groups the features needed for a specific use case into a single array.
videoFeatures bundles playback, volume, time, fullscreen, and more — everything a general video player needs:
import { createPlayer } from '@videojs/react';
import { videoFeatures } from '@videojs/react/video';

const Player = createPlayer({ features: videoFeatures });
Feature bundles are usually paired with specific skins and media elements in a preset. See Presets to learn more.

Create a player with individual features

If you’re not using presets, you can create a player with individual features:
import { createPlayer, playback, volume, time } from '@videojs/react';

const Player = createPlayer({
  features: [playback, volume, time],
});

Extending a feature bundle

Feature bundles are just arrays of features, so extending one is straightforward. For example, if you’re using the /background preset and want a play button on your background video, add the playback feature:
import { createPlayer, playback } from '@videojs/react';
import { backgroundFeatures } from '@videojs/react/background';

const Player = createPlayer({
  features: [...backgroundFeatures, playback],
});

Access features in components

Access feature state and actions through usePlayer:
// Subscribe to state (re-renders when selected values change)
const { paused, volume } = usePlayer((s) => ({
  paused: s.paused,
  volume: s.volume,
}));

// Call actions
const store = usePlayer();
store.play();
store.setVolume(0.8);
Each feature also has a pre-built selector (e.g. selectPlayback, selectVolume) that returns just that feature’s state and actions:
import { selectPlayback, usePlayer } from '@videojs/react';

const playback = usePlayer(selectPlayback);
playback?.play();

Feature availability

Volume, fullscreen, and picture-in-picture expose an *Availability property because platform support varies. For example, iOS Safari doesn’t allow programmatic volume control.
ValueMeaning
'available'Ready to use
'unavailable'Could work, not ready yet
'unsupported'Platform can never do this
Components that depend on availability (like PiPButton and FullscreenButton) expose a data-availability attribute, so you can hide unsupported controls with CSS:
.pip-button[data-availability="unsupported"] {
  display: none;
}
You can also check availability in JavaScript:
function PiPControl() {
  const availability = usePlayer((s) => s.pipAvailability);

  if (availability === 'unsupported') return null;

  return <PiPButton />;
}

Available features

playback

paused state and play() / pause() actions. The foundation of any player.

volume

volume (0–1) and muted state, setVolume() and toggleMuted() actions. Includes volumeAvailability.

time

currentTime and duration state, seek() action.

fullscreen

fullscreen state and requestFullscreen() / exitFullscreen() actions. Includes fullscreenAvailability.

pip

Picture-in-picture state and requestPictureInPicture() / exitPictureInPicture() actions. Includes pipAvailability.

textTrack

Subtitle, caption, chapter, and thumbnail track state. toggleSubtitles() action.

playbackRate

playbackRate state and setPlaybackRate() action.

controls

Tracks user activity to show or hide controls.

source

Media source state for the current loaded source.

error

error state and dismissError() action for media errors.

buffer

buffering state and buffer progress.

Build docs developers (and LLMs) love