Joe1992
Joe1992

Reputation: 468

getPlaylist returns an array with only one video when using the Youtube IFrame API

I'm trying to make a webpage that will load a given Youtube playlist and play a random video from it.

I'm struggling getting the playlist information from the API as when I run

player.getPlaylist()

the API returns an array of one element (the currently cued video) every time, regardless of the cued video or playlist. My JavaScript is an almost 100% copy/paste from the API documentation and I can't work out why I can't get the full list of videos in the playlist.

<script>

  var tag = document.createElement('script');

  tag.src = "https://www.youtube.com/iframe_api";
  var firstScriptTag = document.getElementsByTagName('script')[0];
  firstScriptTag.parentNode
    .insertBefore(tag, firstScriptTag);

  var player;
  function onYouTubeIframeAPIReady() {
    player = new YT.Player('player', {
      height: '390',
      width: '640',
      playerVars: {
        listType: 'playlist',
        list: 'PLbIZ6k-SE9SiarIg09JXUdK2kDX5_OB25',
        autoplay: 0,
        controls: 1
      },
      events: {
        'onReady': onPlayerReady,
        'onStateChange': onPlayerStateChange
      }
    });
  }

  function onPlayerReady(event) {
    console.log(event.target.getPlaylist());
  }

  var done = false;
  function onPlayerStateChange(event) {
    if (event.data == YT.PlayerState.ENDED && !done) {
      done = true;
      console.log('Video Finished');
      stopVideo();
    }
  }
  function stopVideo() {
    player.stopVideo();
  }
</script>

Can anybody lend a hand and point to my mistake or in the right direction?

Upvotes: 4

Views: 1803

Answers (1)

spenibus
spenibus

Reputation: 4409

It seems the playlist is not actually cued when loaded this way but only the first video. This is confirmed by getPlaylist() returning only one video and the onStateChange event not firing once the player has loaded.

We can however force the player to cue the playlist with cuePlaylist(). What is described below can be seen in this JSFiddle.

We modify the constructor to load nothing:

playerVars: {
    autoplay: 0,
    controls: 1
},

We modify onPlayerReady() to cue the playlist:

function onPlayerReady(event) {
    event.target.cuePlaylist({
        listType: 'playlist',
        list: 'PLbIZ6k-SE9SiarIg09JXUdK2kDX5_OB25',
    });
}

We modify onPlayerStateChange() to check for the CUED state and get the playlist when it fires:

function onPlayerStateChange(event) {

    if (event.data == YT.PlayerState.CUED) {
        console.log(event.target.getPlaylist());
    }

    if (event.data == YT.PlayerState.ENDED && !done) {
        done = true;
        console.log('Video Finished');
        stopVideo();
    }
}

After which the console outputs this:

Array [ "j_OyHUqIIOU", "PK8dsAeMmPk", "lfvceHUBWnU", "Xz5z1hBxejg",
        "OubvTOHWTms", "5WKU7gG_ApU", "XjwO9InuFJk", "lNqChN3WHh8" ]

Upvotes: 3

Related Questions