Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

When using VideoJS the video works fine and all But it doesn't show me the options for the available sources as it should.

I tried using A plugins for the sources and it still doesn't show, Idk what's or why it's doing that maybe I'm using it in the wrong way or perhaps the sources is automatically hidden by default or it's just bugged. Does anyone know how to fix it?

My Code NOTE: Sources comes from another Component and It's been tested it should work find when used.

import React from 'react';
import videojs from 'video.js';
import 'video.js/dist/video-js.css';
import "videojs-hotkeys";
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);
  }, [onReady, 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 className='w-100 h-100' data-vjs-player >
      <div ref={videoRef}  className='w-100 h-100' />
export default function Videojs({sources}){
// Video Options
  const videoJsOptions = {
    responsive: true,
    controls: true,
    playbackRates: [0.5, 1, 1.5, 2],
    preload: 'auto',
    plugins: {
        hotkeys: {
        volumeStep: 0.1,
        seekStep: 5,
        enableModifiersForNumbers: false
    sources: sources.map(item => {
      return {
        src: item.url,
        type: item.isM3U8 && 'application/x-mpegURL',
        quality: item.quality
  return(
    <div className='h-100 w-100'>
      <VideoJS options={videoJsOptions} />
                To achieve this, you'll need to use the videojs-contrib-quality-levels and videojs-hls-quality-selector plugins as far as I know. LE: after a little researach I found other plugin more up to date: videojs-resolution-switcher plugin
– Stefan
                Mar 16 at 13:48
                Thanks, But I already tried plugins, videojs-contrib-quality-levels Doesn't work. videojs-hls-quality-selector Doesn't support HLS And videojs-resolution-switcher When trying to install it using NPM it gives me an Error. ``` npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree ```
– Viper
                Mar 16 at 14:29

Viper, I am aware now that you tried the plugins I specified earlier and you remembered me of an old project of mine where I got a similar problem and what I made was the following. (Note that this was a solution for me some time ago)

<-- old code removed -->

This should work but you have to adapt it to display available source options.

LE: I've tried to update the code based on videojs documentation as videojs.extend() method has been removed on latest versions.

<-- new code here -->

import videojs from 'video.js';
const SourceSelector = videojs.extend(videojs.getComponent('MenuButton'), {
  constructor: function (player, options) {
    videojs.getComponent('MenuButton').apply(this, arguments);
    this.controlText('Source');
  createItems: function () {
    const player = this.player();
    const sources = player.options().sources;
    const currentSourceIndex = sources.findIndex(
      (source) => source.src === player.currentSrc()
    const items = sources.map((source, index) => {
      return new videojs.MenuItem(player, {
        label: source.quality || source.type,
        index: index,
        selected: index === currentSourceIndex,
    return items;
  buildCSSClass: function () {
    return 'vjs-source-selector vjs-menu-button vjs-menu-button-popup     vjs-control vjs-button';
                I think I'm doing something wrong, I tried doing what you just said but it gives me an error now. Could you please explain to me more or show me how the code is supposed to be applied?
– Viper
                Mar 16 at 17:22
                Yea, so based on their documentation, they removed  videojs.extend() method. check this videojs.com/guides/components and this videojs.com/guides/videojs-7-to-8  above you can find an adapted code for this issue. hope it helps you.
– Stefan
                Mar 17 at 8:39
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.