Questions about the YouTube player_api code


#276

Got it, thank you.

Are there further improvements, or is that it and this one is good?
https://jsfiddle.net/89zwf62y/19/

  function combineSettings(oldSettings, newSettings) {
        const oldPlayerVars = oldSettings.playerVars;
        const newPlayerVars = newSettings.playerVars;
        const settings = Object.assign({}, oldSettings, newSettings);
        settings.playerVars = Object.assign({}, oldPlayerVars, newPlayerVars);
        return settings;
    }

#277

Google Chrome Inspect

On page load

What seems to be the issue with .forEach, and how would that be fixed?

There should only be 4 requests appearing on page load.

Also, the images were taken from Blogger / Blogspot, not jsfiddle.

widjets.js should be the only script that appears on page load. Like how it’s shown with the for loop code.

for loop
https://testblogerlayout.blogspot.com/

jsfiddle:
https://jsfiddle.net/g6oaht8f/118/

image

      function onPlayerStateChange(event) {
        if (event.data == YT.PlayerState.PLAYING) {
          const temp = event.target;
          for (let i = 0; i < players.length; i++) {
            if (players[i] != temp) players[i].pauseVideo();
          }
        }
        const player = event.target;
        const playerVars = player.b.b.playerVars;
        if (playerVars.loop && event.data === YT.PlayerState.ENDED) {
          player.seekTo(playerVars.start);
        }
      }

vs.

forEach
https://test2codes.blogspot.com/

jsfiddle:
https://jsfiddle.net/g6oaht8f/106/

image

      function onPlayerStateChange(event) {
          const player = event.target;
          if (event.data === YT.PlayerState.PLAYING) {
              const otherVideos = (video) => video !== player;
              const pauseVideo = (video) => video.pauseVideo();
              players.filter(otherVideos).forEach(pauseVideo);
          }
          const playerVars = player.b.b.playerVars;
          if (playerVars.loop && event.data === YT.PlayerState.ENDED) {
              player.seekTo(playerVars.start);
          }
      }

#278

I think it likes it set up like this instead:
https://jsfiddle.net/g6oaht8f/120/

        function onPlayerStateChange(event) {
            if (event.data === YT.PlayerState.PLAYING) {
                players.forEach(function pauseOtherVideos(player) {
                    if (player !== event.target) {
                        player.pauseVideo();
                    }
                });
            }
            const player = event.target;
            const playerVars = player.b.b.playerVars;
            if (playerVars.loop && event.data === YT.PlayerState.ENDED) {
                player.seekTo(playerVars.start);
            }
        }

or this way:
https://jsfiddle.net/g6oaht8f/122/

 function onPlayerStateChange(event) {
      if (event.data === YT.PlayerState.PLAYING) {
          players.filter(function otherVideos(player) {
              return player !== event.target;
          }).forEach(function pauseVideo(player) {
              player.pauseVideo();
          });
      }
      const player = event.target;
      const playerVars = player.b.b.playerVars;
      if (playerVars.loop && event.data === YT.PlayerState.ENDED) {
          player.seekTo(playerVars.start);
      }
  }

or this way:
https://jsfiddle.net/g6oaht8f/125/

  function onPlayerStateChange(event) {
      function otherVideos(player) {
          return player !== event.target;
      }

      function pauseVideo(player) {
          player.pauseVideo();
      }
      if (event.data === YT.PlayerState.PLAYING) {
          players.filter(otherVideos).forEach(pauseVideo);
      }
      const player = event.target;
      const playerVars = player.b.b.playerVars;
      if (playerVars.loop && event.data === YT.PlayerState.ENDED) {
          player.seekTo(playerVars.start);
      }
  }

or this way:
https://jsfiddle.net/g6oaht8f/127/

    function onPlayerStateChange(event) {
        if (event.data === YT.PlayerState.PLAYING) {
            const otherVideos = (player) => player !== event.target;
            const pauseVideo = (player) => player.pauseVideo();
            players.filter(otherVideos).forEach(pauseVideo);
        }
        const player = event.target;
        const playerVars = player.b.b.playerVars;
        if (playerVars.loop && event.data === YT.PlayerState.ENDED) {
            player.seekTo(playerVars.start);
        }
    }

Update: That’s odd.
Now only 4 requests are appearing inside.
Before there were 7.
http://test2codes.blogspot.com/

But it doesn’t seem to like it for this way for some reason:
https://jsfiddle.net/g6oaht8f/106/

      function onPlayerStateChange(event) {
          const player = event.target;
          if (event.data === YT.PlayerState.PLAYING) {
              const otherVideos = (video) => video !== player;
              const pauseVideo = (video) => video.pauseVideo();
              players.filter(otherVideos).forEach(pauseVideo);
          }
          const playerVars = player.b.b.playerVars;
          if (playerVars.loop && event.data === YT.PlayerState.ENDED) {
              player.seekTo(playerVars.start);
          }
      }

#279

I’m only getting 4 request as you said too.

What doesn’t it like about that?


#280

Update: That’s odd.
Now only 4 requests are appearing inside.
Before there were 7.

It was just something I had noticed, it seems to have disappeared…

It seems to be fine now.


#281

I figured out how to get this to work without load.js
https://jsfiddle.net/g6oaht8f/239/

const load = (function makeLoad() {
    "use strict";

    function _load(tag) {
        return function(url) {
            return new Promise(function(resolve) {
                const element = document.createElement(tag);
                const parent = "body";
                const attr = "src";
                element.onload = function() {
                    resolve(url);
                };
                element[attr] = url;
                document[parent].appendChild(element);
            });
        };
    }
    return {
        js: _load("script")
    };
}());

    function init(video, settings) {
        load.js("https://www.youtube.com/player_api").then(function() {
            YT.ready(function() {
                addVideo(video, settings);
            });
        });
    }

Delete all of the load.js code.
All of the above code.

Just keep this part,
https://jsfiddle.net/g6oaht8f/243/

  function init(video, settings) {
            YT.ready(function() {
                addVideo(video, settings);
            });
        
    }

and then add the script to the html.
<script type="text/javascript" src="https://www.youtube.com/player_api"></script>

I think I did this right, unless you think there’s a different, better way it could’ve been done. or, just an improvement I could’ve made to it.


#282

Earlier load was required when you wanted to delay loading player_api until after a button was clicked.

As that doesn’t seem to be important to you anymore, there’s no need for that load section.


#283

There’s still a load section in here?
https://jsfiddle.net/g6oaht8f/243/

All of this was removed:

Only these two scripts show on page load:

widgetapi.js 0 B
player_api 859 B

What else would be removed, I don’t get it.

This would be it, right?

const load = (function makeLoad() {
    "use strict";

    function _load(tag) {
        return function(url) {
            return new Promise(function(resolve) {
                const element = document.createElement(tag);
                const parent = "body";
                const attr = "src";
                element.onload = function() {
                    resolve(url);
                };
                element[attr] = url;
                document[parent].appendChild(element);
            });
        };
    }
    return {
        js: _load("script")
    };
}());

And this:
load.js("https://www.youtube.com/player_api").then(function() {

And that would simply be changed to this:
Unless I would do something different here?

  function init(video, settings) {
            YT.ready(function() {
                addVideo(video, settings);
            });
        
    }

#284

You only needed that load code when you wanted to delay the loading of player_api until the button was clicked.


#285

I was just messing with the code:
Seeing how I would get it to work without the load code:
https://jsfiddle.net/g6oaht8f/243/

Using this instead:
<script type="text/javascript" src="https://www.youtube.com/player_api"></script>

Then I did it right then.
Meaning, I removed the right stuff.


#286

Now that you don’t care about delaying player_api until a button is clicked, you don’t need the load code.


#287

Isn’t the load code removed from here?
https://jsfiddle.net/g6oaht8f/243/


#288

That question is not relevant to what I was saying.


#289

I was just making a different version, one that didn’t use the load code, that’s all.

I like the load code.


#290

Question 1.)

If setLoop was being used here, would it go inside of the ‘if’, or stay outside of it?

https://jsfiddle.net/qnbyg5x9/291/

  function onPlayerStateChange(event) {
    const player = event.target;
    // Outside of 'if' player.setLoop(true);

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

Question 2.)

If loop can be used in the playerVars
https://developers.google.com/youtube/player_parameters#loop

 playerVars: {
loop:1
},

What would be the purpose of using loop outside of the playerVars?

Long Version:
const loopPlaylists = true;
player.setLoop(loopPlaylists);

/

Shortcut:
player.setLoop(true);


#291

@Paul_Wilkins

Would setLoop actually go inside onPlayerReady instead?
https://jsfiddle.net/qnbyg5x9/303/

 function onPlayerReady(event) {
    const player = event.target;
    player.setVolume(0); // percent
    player.setLoop(true);
  }

Then only Question 2.) is left. #290

If loop can be used in the playerVars
https://developers.google.com/youtube/player_parameters#loop

 playerVars: {
loop:1
},

What would be the purpose of using loop outside of the playerVars ?


#292

I wouldn’t think so. onPlayerReady is when the youtubeapi is ready, but it’s not when the playlist has been loaded. However, the api says that the setting persists even when other playlists are loaded. As the api remembers that setLoop information that is set, and you are not using multiple playlists with different loop requirements, onPlayerReady is a suitable place to put it.

I think that’s where it must be, as the API only understands loop when it’s there.

The API knows nothing about loop when it’s anywhere outside of playerVars.