Playing YouTube videos from an array

With that code.

This doesn’t work in the code.
https://jsfiddle.net/0pc49nqb/2/

It gets disabled.

  managePlayer.add(".playc", {
    start: 40
  });

start: 40 still works with this:
https://jsfiddle.net/6ug2r7xt/3/

  let hasShuffled = false;

    function onStateChange(event) {
        const player = event.target;

        if (!hasShuffled) {
            player.setShuffle(true);
            player.playVideoAt(0);
            hasShuffled = true;
        }
    }

With the above code it shouldn’t be playerVars as the init parameter. That should be playerOptions instead. That way you can assign to defaults just the playerOptions and it works.

Is this what you mean?
https://jsfiddle.net/c4nz7qa9/1/

    function init(playerOptions) {
    Object.assign(defaults.playerVars, playerOptions);
  }

After adding a looping option, the middle playlist video stopped working.

https://jsfiddle.net/gm94orne/1/

  function setLooping(defaults, video) {
    defaults.playerVars.loop = 1;
    defaults.playerVars.playlist = video.dataset.id;
  }

  function addPlayer(video, settings, videoIds = video.dataset.id) {
    const videoId = !Array.isArray(videoIds) && videoIds;
    const playlist = Array.isArray(videoIds) && videoIds.join();
    const defaults = {
      height: 640,
      host: "https://www.youtube-nocookie.com",
      videoId,
      width: 360
    };
    defaults.playerVars = {
      playlist: playlist || undefined
    };

    defaults.events = {
      "onReady": onPlayerReady
    };

    const defaultVars = defaults.playerVars;
    const playerVars = settings.playerVars;
    defaults.playerVars = Object.assign({}, defaultVars, playerVars);
    setLooping(defaults, video);
    const player = new YT.Player(video, defaults);
    players.push(player);
    return player;
  }

Should be how it works.
loop:1 enabled
loop:0 disabled

The video loops, but there is not a way for you to tell it not to loop inside the managePlayer.

by default it should be disabled, unless stated: loop:1.

  managePlayer.add(".playc", {
    loop:1
  });

Right now you are dumping all of the playerOptions into the playerVars area, where none of it is intended to go.

Get rid of the playerVars (keeping defaults) and that will be what I mean.

Once you have that done correctly we can move on to other things from there.

1 Like

Like this? That looks better.

  function createPlayerOptions(settings) {
    const defaultOptions = defaults.playerVars;
    const playerVars = Object.assign({}, defaultOptions, settings);
    return defaults;
  }
  function init(playerOptions) {
    Object.assign(defaults, playerOptions);
  }

If the above is good, I added the looping code to it.

Here
https://jsfiddle.net/8zcthL2b/1/

This is what I added, after I did that, the middle playlist video does not go on.

  function setLooping(defaults, video) {
    defaults.playerVars.loop = 1;
    defaults.playerVars.playlist = video.dataset.id;
  }

setLooping(defaults, video);

  defaults.playerVars = {
    loop: 0,
}
  managePlayer.add(".playc", {
    loop: 1
  });

No that’s not good yet because anytime playerOptions contains playerVars, that destroys the existing defaults.playerVars.

As you might be able to tell by now, combining objects is tricky to do right.

There is a good solution to all of this though. There’s a code library out there that’s well designed to make it easy for us to combine objects. Shall we take a look at that instead.

What is the best I can get Code 1 & Code 2 to be short of using a code library?

Both codes currently work as they are, but both may need to be written a little differently, is what you may be saying.

Work as they are, meaning, the settings and playlists all work in the codes.

Whichever code you would like to start with first, unless, the instructions to adjust both would be simple to do.

Code 1 uses this:
https://jsfiddle.net/c0a7kdws/

const defaults = {
    playerOptions: {
      playerVars: {
        autoplay: 0,
        controls: 0,
        disablekb: 1,
        enablejsapi: 1,
        fs: 0,
        iv_load_policy: 3,
        rel: 0
      }
    }
  };

  function createPlayerOptions(settings) {
    const defaultOptions = defaults.playerOptions;
    const playerOptions = defaultOptions.playerVars;
    const playerVars = Object.assign({}, playerOptions, settings);
    playerOptions.playerVars = playerVars;
    return playerOptions;
  }

  function init(playerOptions) {
    Object.assign(defaults.playerOptions, playerOptions);
  }

Code 2 uses this:
https://jsfiddle.net/xs9gL24c/

  const defaults = {};
  defaults.playerVars = {
    autoplay: 0,
    controls: 0,
    disablekb: 1,
    enablejsapi: 1,
    fs: 0,
    iv_load_policy: 3
  };

  function createPlayerOptions(settings) {
    const defaultOptions = defaults.playerVars;
    const defaultPlayerVars = defaultOptions.playerVars;
    const playerVars = Object.assign({}, defaultPlayerVars, settings);
    defaults.playerVars = playerVars;
    return defaults;
  }
 
  function init(playerOptions) {
    Object.assign(defaults, playerOptions);
  }

That would be achieved by us creating a separate function to combine two sets of playerOptions.

The function should have two parameters, one for the target object and one for the source object. Inside of the function we assign to the target object the source object. Then after that, we assign to the target playerVars the source playerVars. That function should be suitable to be used in several places throughout the code.

The code might seem to be working, but the playerVars are currently not working properly in the code.

Is this better?

I just fixed Code 2

Added: defaults.playerVars = playerVars;

Now the playerVars are working.
https://jsfiddle.net/xs9gL24c/

  function createPlayerOptions(settings) {
    const defaultOptions = defaults.playerVars;
    const defaultPlayerVars = defaultOptions.playerVars;
    const playerVars = Object.assign({}, defaultPlayerVars, settings);
    defaults.playerVars = playerVars;
    return defaults;
  }

Which is now inline with Code 1
https://jsfiddle.net/c0a7kdws/

  function createPlayerOptions(settings) {
    const defaultOptions = defaults.playerOptions;
    const playerOptions = defaultOptions.playerVars;
    const playerVars = Object.assign({}, playerOptions, settings);
    playerOptions.playerVars = playerVars;
    return playerOptions;
  }

.playa & .playc

have
start: 45;

Which allows me to test the settings after I make changes in the code.

If those don’t work, it means I messed up somewhere.

It’s hard for me to figure these out because, I only go by, if I place one thing somewhere and everything works, I think there is nothing wrong.

The only way I can tell if something is wrong, is if the code stops working.

15 posts were split to a new topic: Using tests to help us combine two objects