Why is playVideo() not in the code?

Good one - was is successful?

None of the videos are working in your updated code post #20 when they are clicked on, how come?

https://jsfiddle.net/8tpyevbc/

Last working version: Post #17
https://jsfiddle.net/pmw57/94L3ra28/

Okay, the code from my previous post #17 all works, so I’ll progress from there making the post #20 code changes more slowly, testing as I go along.

The code changes are:

  • removing unused player variable
  • use the players array instead
  • find the appropriate player
  • simplify by extracting code out to functions

After doing all that I find that things still continue to work.

When comparing the new code with the previous code, I left something in the previous code that shouldn’t have been left there.

        disablekb: 1,
        playlist: ""

Removing that playlist results in things working.

        disablekb: 1

After also making several changes to keep JSLint happy, we end up with the code at https://jsfiddle.net/5dn396jf/1/

There’s an issue.

playVideo is only working on the middle player.

The top 3 videos, .the videos don’t start right away when clicked on.

Also on the grid videos.

When testing the code,

Autoplay has to be set to 0.
autoplay: 0,

https://jsitor.com/y5bbacrk-_

https://jsfiddle.net/c8uxf0td/

  function play(playerIndex) {
    players[playerIndex].playVideo();
  }
  return {
    addPlayer,
    play
  };
}());

Is that problem happening on the code that I updated? https://jsfiddle.net/5dn396jf/1/

Issue 1 Yes it is.

I tested it here.
https://jsitor.com/y5bbacrk-_

Issue 2 There’s also another issue, none of the set properties are working.

    initPlayer({
        end: 280,
        loop: true,
        start: 0,
        target: ".alpha"
    });

The code that uses loadplayer is the last version where the properties were working properly.

Here: https://jsfiddle.net/5p4ug2mn/

loadPlayer({
    target: ".jacket-middle",
    width: 277,
    height: 207,
    start: 4
  });
  loadPlayer({
    target: ".jacket-right",
    width: 277,
    height: 207
  });

  loadPlayer({
    target: ".jacketc",
    width: 600,
    height: 338,
    loop: true,
    playlist
  });

Issue 3 There’s also an issue with the middle player.

After the first video finishes, it replays the same video and doesn’t go on to the next video.

Issue 4 Also, it’s supposed to be a random video that plays from the list, it keeps playing the same video .

The code that uses loadplayer is the last version where both those things were working.
https://jsfiddle.net/5p4ug2mn/

let hasShuffled = false;

  function onPlayerStateChange(event) {
    const player = event.target;
    if (!hasShuffled) {
      player.setShuffle(true);
      player.playVideoAt(0);
      hasShuffled = true;
    }

It looks like we are in need of a better way to test the code, than just checking of a video starts playing.

Fortunately there are many solutions for that.

My idea would be getting

  function play() {
    player.playVideo();
  }

To work in here:
https://jsfiddle.net/d2kc875t/1/

Keeping the covers at the top.

Making improvements from there that don’t break the code.

Just editing the YouTube code, leaving the covers at the top.

(function manageCover() {
   "use strict";

   function hide(el) {
      el.classList.add("hide");
   }

   function coverClickHandler(evt) {
      const cover = evt.currentTarget;
      hide(cover);
   }
   const cover = document.querySelector(".jacket-left");
   cover.addEventListener("click", coverClickHandler);
}());

(function manageCover() {
   "use strict";

   function hide(el) {
      el.classList.add("hide");
   }

   function coverClickHandler(evt) {
      const cover = evt.currentTarget;
      hide(cover);
   }
   const cover = document.querySelector(".jacket-middle");
   cover.addEventListener("click", coverClickHandler);
}());

(function manageCover() {
   "use strict";

   function hide(el) {
      el.classList.add("hide");
   }

   function coverClickHandler(evt) {
      const cover = evt.currentTarget;
      hide(cover);
   }
   const cover = document.querySelector(".jacket-right");
   cover.addEventListener("click", coverClickHandler);
}());
(function manageCover() {
   "use strict";

   function hide(el) {
      el.classList.add("hide");
   }

   function coverClickHandler(evt) {
      const cover = evt.currentTarget;
      hide(cover);
   }
   const cover = document.querySelector(".jacketc");
   cover.addEventListener("click", coverClickHandler);
}());

(function manageCover() {
   "use strict";

   function show(el) {
      el.classList.remove("hide");
   }

   function hide(el) {
      el.classList.add("hide");
   }

   function coverClickHandler(evt) {
      const cover = evt.currentTarget;
      const thewrap = cover.parentNode.querySelector(".wraph");
      hide(cover);
      show(thewrap);
   }
   const cover = document.querySelector(".jacketd");
   cover.addEventListener("click", coverClickHandler);
}());

const videoPlayer = (function makeVideoPlayer() {
  "use strict";
  const players = [];
  let playerVars = {};
  let player = null;

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

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

  let hasShuffled = false;

  function onPlayerStateChange(event) {
    const player = event.target;
    if (!hasShuffled) {
      player.setShuffle(true);
      player.playVideoAt(0);
      hasShuffled = true;
    }
    if (event.data === YT.PlayerState.PLAYING) {
      for (let i = 0; i < players.length; i++) {
        if (players[i] !== event.target) players[i].pauseVideo();
      }
    }

    if (playerVars.loop && event.data === YT.PlayerState.ENDED) {
      player.seekTo(playerVars.start);
    }
  }

  function addPlayer(video, settings) {
    playerVars = Object.assign({
      videoId: video.dataset.id,
      host: "https://www.youtube-nocookie.com",
      events: {
        "onReady": onPlayerReady,
        "onStateChange": onPlayerStateChange
      }
    }, settings);
    players.push(new YT.Player(video, playerVars));

  }

  function play() {
    player.playVideo();
  }
  return {
    addPlayer,
    play
  };
}());

function loadPlayer(opts) {
  "use strict";

  function show(el) {
    el.classList.remove("hide");
  }

  function initPlayer(wrapper) {
    const video = wrapper.querySelector(".video");
    opts.width = opts.width || 198;
    opts.height = opts.height || 198;
    opts.autoplay = 0;
    opts.controls = 1;
    opts.rel = 0;
    opts.enablejsapi = 1;
    opts.iv_load_policy = 3;
    opts.fs = 0;
    opts.disablekb = 1;

    function paramInOpts(settings, param) {
      if (opts[param] !== undefined) {
        settings[param] = opts[param];
      }
      return settings;
    }
    const settingsParams = ["width", "height", "videoid", "host"];
    const settings = settingsParams.reduce(paramInOpts, {});
    const playerVarsParams = ["autoplay", "cc_load_policy",
      "controls", "disablekb", "end", "fs", "iv_load_policy",
      "list", "listType", "loop", "playlist", "rel", "start"
    ];
    settings.playerVars = playerVarsParams.reduce(paramInOpts, {});
    videoPlayer.addPlayer(video, settings);
  }

  function coverClickHandler(evt) {
    const wrapper = evt.currentTarget.nextElementSibling;
    show(wrapper);
    initPlayer(wrapper);
  }
  const cover = document.querySelector(opts.target);
  cover.addEventListener("click", coverClickHandler);
}
const playlist = "0dgNc5S8cLI,mnfmQe8Mv1g,-Xgi_way56U,CHahce95B1g";

function onYouTubeIframeAPIReady() {
  loadPlayer({
    target: ".jacket-left",
    width: 277,
    height: 207
  });

  loadPlayer({
    target: ".jacket-middle",
    width: 277,
    height: 207,
    start: 4
  });
  loadPlayer({
    target: ".jacket-right",
    width: 277,
    height: 207
  });

  loadPlayer({
    target: ".jacketc",
    width: 600,
    height: 338,
    loop: true,
    playlist
  });
  loadPlayer({
    target: ".alpha",
    start: 0,
    end: 280,
    loop: true
  });
  loadPlayer({
    target: ".beta",
    start: 0,
    end: 240,
    loop: true
  });
  loadPlayer({
    target: ".gamma",
    start: 0,
    end: 265,
    loop: true
  });
  loadPlayer({
    target: ".delta",
    start: 4,
    end: 254,
    loop: true
  });
  loadPlayer({
    target: ".epsilon",
    start: 0,
    end: 242,
    loop: true
  });
  loadPlayer({
    target: ".zeta",
    start: 0,
    end: 285,
    loop: true
  });
  loadPlayer({
    target: ".eta",
    start: 23,
    end: 312,
    loop: true
  });
  loadPlayer({
    target: ".theta",
    start: 2
  });
  loadPlayer({
    target: ".iota"
  });
}

Keeping the covers at the top of the code, getting

  function play() {
    player.playVideo();
  }

to work in the code, is that something that can be done?

Putting the code through jslint I get these errors:

https://jsfiddle.net/zxuwormp/

1. Redefinition of 'manageCover' from line 1.
(function manageCover() {
31: 112. Redefinition of 'manageCover' from line 1.
(function manageCover() {
45: 113. Redefinition of 'manageCover' from line 1.
(function manageCover() {
60: 114. Redefinition of 'manageCover' from line 1.
(function manageCover() {
7. Expected property 'host' to be ordered before property 'videoId'.
            host: "https://www.youtube-nocookie.com",
124: 138. Expected property 'events' to be ordered before property 'host'.
            events: {

All of this stuff here is good as it is.

const videoPlayer = (function makeVideoPlayer() {
    "use strict";
    const players = [];
    let playerVars = {};
    let player = null;

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

    function onPlayerReady(event) {
        player = event.target;
        player.setVolume(100); // percent
    }

    let hasShuffled = false;

    function onPlayerStateChange(event) {
            player = event.target;
        if (!hasShuffled) {
            player.setShuffle(true);
            player.playVideoAt(0);
            hasShuffled = true;
        }

        if (event.data === YT.PlayerState.PLAYING) {
            players.forEach(function pauseOtherVideos(player) {
                if (player !== event.target) {
                    player.pauseVideo();
                }
            });
        }

        if (playerVars.loop && event.data === YT.PlayerState.ENDED) {
            player.seekTo(playerVars.start);
        }
    }

To get rid of the Redefinition of 'manageCover

This post deals with that:

https://www.sitepoint.com/community/t/im-receiving-a-script-error/371086/36

The redefinition part, manageCover is different though.

I thought it was dealing with the same issue, it might be different.

I tried to do something like this but wasn’t able to get it to work in the code.

 function addPlayer(video, settings) {
      playerVars = Object.assign({
      const config = {
        videoId: video.dataset.id,
        host: "https://www.youtube-nocookie.com"
      }
      config.events = {
        "onReady": onPlayerReady,
        "onStateChange": onPlayerStateChange
      };
    }, settings); players.push(new YT.Player(video, playerVars));

}

I fixed the redefinition of manageCover issue.

https://jsfiddle.net/j1s3neyr/

I don’t know how to add this:
https://jsfiddle.net/vLyabstr/

const config = {
host: "https://www.youtube-nocookie.com",
videoId: video.dataset.id,
};

config.events = {
"onReady": onPlayerReady,
"onStateChange": onPlayerStateChange
 };

to this:

    function addPlayer(video, settings) {
        playerVars = Object.assign({
            host: "https://www.youtube-nocookie.com",
            videoId: video.dataset.id,
            events: {
                "onReady": onPlayerReady,
                "onStateChange": onPlayerStateChange
            }
        }, settings);
        players.push(new YT.Player(video, playerVars));
    }

So jslint is fine with it.

These are the errors that are left:
https://jsfiddle.net/7cwpjtuk/

  1. Expected property ‘events’ to be ordered before property ‘videoId’.
    events: {
    200: 92. Expected property ‘height’ to be ordered before property ‘width’.
    height: 207
    206: 93. Expected property ‘height’ to be ordered before property ‘width’.
    height: 207,
    212: 94. Expected property ‘height’ to be ordered before property ‘width’.
    height: 207
    218: 95. Expected property ‘height’ to be ordered before property ‘width’.
    height: 338,
    224: 96. Expected property ‘start’ to be ordered before property ‘target’.
    start: 0,

I once tried to order those in the order jslint wants, I did, then the code stopped working.

I can try again and see what happens.

I just changed this:

 function openJacket(cover) {
    hide(cover);
    return cover;
  }

  function showVideo(cover) {
    const thewrap = cover.parentElement.querySelector(".wraph");
    show(thewrap);
  }

  function coverClickHandler(evt) {
    const cover = evt.currentTarget;
    const jacket = openJacket(cover);
    showVideo(cover);
  }

to this:

 function openCover(cover) {
    hide(cover);
    const thewrap = cover.parentElement.querySelector(".wraph");
    show(thewrap);
    return cover;
  }

  function coverClickHandler(evt) {
    const cover = evt.currentTarget;
    const jacket = openCover(cover);
  }

Is that good?
https://jsfiddle.net/6hs7bvx0/1/

or maybe it should be like this?

  function openCover(cover) {
    const thewrap = cover.parentElement.querySelector(".wraph");
    show(thewrap);
    hide(cover); 
  }

  function coverClickHandler(evt) {
    const cover = evt.currentTarget;
    const jacket = openCover(cover);
  }

I think I have settled on this way:
https://jsfiddle.net/b8jL6dre/


  function coverClickHandler(evt) {
    const cover = evt.currentTarget;
    hide(cover); 
    const thewrap = cover.parentElement.querySelector(".wraph");
    show(thewrap);
  }
  
  const cover = document.querySelector(".jacketd");
  cover.addEventListener("click", coverClickHandler);
}());

Code still works.
https://jsfiddle.net/bc63jefq/

Last jslint error remaining.

Which involves doing this I think.

const config = {
host: "https://www.youtube-nocookie.com",
videoId: video.dataset.id
};

config.events = {
"onReady": onPlayerReady,
"onStateChange": onPlayerStateChange
 };

to this:

    function addPlayer(video, settings) {
        playerVars = Object.assign({
            host: "https://www.youtube-nocookie.com",
            videoId: video.dataset.id,
            events: {
                "onReady": onPlayerReady,
                "onStateChange": onPlayerStateChange
            }
        }, settings);
        players.push(new YT.Player(video, playerVars));
    }

I can’t figure out how to do it.

Then work can begin on getting this to work in the code.

  function play() {
    player.playVideo();
  }

jslint had me do this: and it broke the code.
https://jsfiddle.net/dvefrk3n/

    function addPlayer(video, settings) {
        playerVars = Object.assign({
            events: {
                host: "https://www.youtube-nocookie.com",
                "onReady": onPlayerReady,
                "onStateChange": onPlayerStateChange,
                videoId: video.dataset.id
            }
        }, settings);
        players.push(new YT.Player(video, playerVars));
    }

Last working version:
https://jsfiddle.net/bc63jefq/

I got up this far and now I’m stuck.

What does this need to be changed to for jslint to be fine with it?

    function addPlayer(video, settings) {
        playerVars = Object.assign({
            host: "https://www.youtube-nocookie.com",
            videoId: video.dataset.id,
            events: {
                "onReady": onPlayerReady,
                "onStateChange": onPlayerStateChange
            }
        }, settings);
        players.push(new YT.Player(video, playerVars));

    }

No jslint errors here, but the code isn’t working properly.

I was able to keep the covers at the top of the code.

There’s no issue with the other code.
https://jsfiddle.net/mLngcw37/

Current Issues:

The middle player has no video showing when clicked.

I tried both ways:

const playlist = "0dgNc5S8cLI,mnfmQe8Mv1g,-Xgi_way56U,CHahce95B1g";

playlist: "0dgNc5S8cLI,mnfmQe8Mv1g,-Xgi_way56U,CHahce95B1g",

play.Video isn’t working

And none of the custom properties work.

    initPlayer({
        end: 312,
        loop: true,
        start: 23,
        target: ".eta"
    });

Also, some of the code towards the bottom might need to be removed/adjusted since I kept the covers at the top, not sure though.

I’m referring to this part:

function initPlayer(opts) {
    "use strict";

    function show(el) {
        el.classList.remove("hide");
    }

    function getWrapper(cover) {
        return cover.nextElementSibling;
    }

    function getVideo(cover) {
        return getWrapper(cover).querySelector(".video");
    }

    function loadPlayer(cover) {
        const video = getVideo(cover);
        cover.playerIndex = videoPlayer.addPlayer(video, opts);
    }

    function coverClickHandler(evt) {
        const cover = evt.currentTarget;
        const wrapper = getWrapper(cover);
        show(wrapper);
        if (!opts.autoload) {
            loadPlayer(cover);
        }
    }
    const cover = document.querySelector(opts.target);
    cover.addEventListener("click", coverClickHandler);

    if (opts.autoload) {
        loadPlayer(cover);
    }
}

Full Code

(function manageCovera() {
    "use strict";

    function hide(el) {
        el.classList.add("hide");
    }

    function coverClickHandler(evt) {
        const cover = evt.currentTarget;
        hide(cover);
    }
    const cover = document.querySelector(".jacket-left");
    cover.addEventListener("click", coverClickHandler);
}());

(function manageCoverb() {
    "use strict";

    function hide(el) {
        el.classList.add("hide");
    }

    function coverClickHandler(evt) {
        const cover = evt.currentTarget;
        hide(cover);
    }
    const cover = document.querySelector(".jacket-middle");
    cover.addEventListener("click", coverClickHandler);
}());

(function manageCoverc() {
    "use strict";

    function hide(el) {
        el.classList.add("hide");
    }

    function coverClickHandler(evt) {
        const cover = evt.currentTarget;
        hide(cover);
    }
    const cover = document.querySelector(".jacket-right");
    cover.addEventListener("click", coverClickHandler);
}());
(function manageCoverd() {
    "use strict";

    function hide(el) {
        el.classList.add("hide");
    }

    function coverClickHandler(evt) {
        const cover = evt.currentTarget;
        hide(cover);
    }
    const cover = document.querySelector(".jacketc");
    cover.addEventListener("click", coverClickHandler);
}());

(function manageCovere() {
    "use strict";

    function show(el) {
        el.classList.remove("hide");
    }

    function hide(el) {
        el.classList.add("hide");
    }

    function coverClickHandler(evt) {
        const cover = evt.currentTarget;
        hide(cover);
        const thewrap = cover.parentElement.querySelector(".wraph");
        show(thewrap);
    }

    const cover = document.querySelector(".jacketd");
    cover.addEventListener("click", coverClickHandler);
}());


const videoPlayer = (function makeVideoPlayer() {
    "use strict";
    const players = [];

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

    function shuffle(player) {
        const settings = player.settings;
        if (!settings.playlist) {
            return;
        }
        player.setShuffle(true);
        player.playVideoAt(0);
        if (settings.autoplay === 0) {
            player.pauseVideo();
        }
    }

    function onPlayerReady(event) {
        const player = event.target;
        player.setVolume(100); // percent
        shuffle(player);
    }

    function getPlayerIndex(player) {
        const playerIndex = players.findIndex(function compare(thisPlayer) {
            return player === thisPlayer;
        });
        return playerIndex;
    }

    function pauseOtherPlayers(player, state) {
        if (state !== YT.PlayerState.PLAYING) {
            return;
        }
        players.forEach(function pauseVideo(thisPlayer) {
            if (thisPlayer !== player) {
                thisPlayer.pauseVideo();
            }
        });
    }

    function restartPlayerWhenEnded(player, state) {
        if (state !== YT.PlayerState.ENDED) {
            return;
        }
        const settings = player.settings;
        if (settings.loop) {
            player.seekTo(settings.start);
        }
    }

    function onPlayerStateChange(event) {
        const playerIndex = getPlayerIndex(event.target);
        const player = players[playerIndex];
        const state = event.data;

        pauseOtherPlayers(player, state);
        restartPlayerWhenEnded(player, state);
    }

    function updateParams(playerParams, params) {
        const entries = Object.entries(params);
        entries.forEach(function updateParam([key, value]) {
            if (playerParams.hasOwnProperty(key)) {
                playerParams[key] = value;
            }
        });
        return playerParams;
    }

    function addPlayer(video, settings) {
        const playerParamDefaults = {
            height: 198,
            host: "https://www.youtube-nocookie.com",
            videoId: video.dataset.id,
            width: 198
        };
        playerParamDefaults.playerVars = {
            autoplay: 0,
            cc_load_policy: 0,
            controls: 1,
            disablekb: 1,
            enablejsapi: 1,
            fs: 0,
            iv_load_policy: 3,
            loop: 0,
            rel: 0
        };
        playerParamDefaults.events = {
            "onReady": onPlayerReady,
            "onStateChange": onPlayerStateChange
        };

        const playerParams = updateParams(playerParamDefaults, settings);
        const playerVars = updateParams(playerParams.playerVars, settings);
        playerParams.playerVars = playerVars;
        const playerIndex = players.length;
        const player = new YT.Player(video, playerParams);
        player.settings = settings;
        players[playerIndex] = player;
        return playerIndex;
    }

    function play(playerIndex) {
        players[playerIndex].playVideo();
    }
    return {
        addPlayer,
        play
    };
}());

function initPlayer(opts) {
    "use strict";

    function show(el) {
        el.classList.remove("hide");
    }

    function getWrapper(cover) {
        return cover.nextElementSibling;
    }

    function getVideo(cover) {
        return getWrapper(cover).querySelector(".video");
    }

    function loadPlayer(cover) {
        const video = getVideo(cover);
        cover.playerIndex = videoPlayer.addPlayer(video, opts);
    }

    function coverClickHandler(evt) {
        const cover = evt.currentTarget;
        const wrapper = getWrapper(cover);
        show(wrapper);
        if (!opts.autoload) {
            loadPlayer(cover);
        }
    }
    const cover = document.querySelector(opts.target);
    cover.addEventListener("click", coverClickHandler);

    if (opts.autoload) {
        loadPlayer(cover);
    }
}

const playlist = "0dgNc5S8cLI,mnfmQe8Mv1g,-Xgi_way56U,CHahce95B1g";

function onYouTubeIframeAPIReady() {
    initPlayer({
        height: 207,
        target: ".jacket-left",
        width: 277
    });
    initPlayer({
        height: 207,
        start: 4,
        target: ".jacket-middle",
        width: 277
    });
    initPlayer({
        height: 207,
        target: ".jacket-right",
        width: 277
    });
    initPlayer({
        height: 338,
        loop: true,
        playlist: "0dgNc5S8cLI,mnfmQe8Mv1g,-Xgi_way56U,CHahce95B1g",
        target: ".jacketc",
        width: 600
    });
    initPlayer({
        end: 280,
        loop: true,
        start: 0,
        target: ".alpha"
    });
    initPlayer({
        end: 240,
        loop: true,
        start: 0,
        target: ".beta"
    });
    initPlayer({
        end: 265,
        loop: true,
        start: 0,
        target: ".gamma"
    });
    initPlayer({
        end: 254,
        loop: true,
        start: 4,
        target: ".delta"
    });
    initPlayer({
        end: 242,
        loop: true,
        start: 0,
        target: ".epsilon"
    });
    initPlayer({
        end: 285,
        loop: true,
        start: 0,
        target: ".zeta"
    });
    initPlayer({
        end: 312,
        loop: true,
        start: 23,
        target: ".eta"
    });
    initPlayer({
        start: 2,
        target: ".theta"
    });
    initPlayer({
        target: ".iota"
    });
}

The code works properly here:
Meaning all the custom properties work and all the videos play.

https://jsfiddle.net/84jcb2xa/

play.Video doesn’t work,

jslint wants this to be reorganized.

   function addPlayer(video, settings) {
        playerVars = Object.assign({
            host: "https://www.youtube-nocookie.com",
            videoId: video.dataset.id,
            events: {
                "onReady": onPlayerReady,
                "onStateChange": onPlayerStateChange
            }
        }, settings);
        players.push(new YT.Player(video, playerVars));
    }

Full Code

const videoPlayer = (function makeVideoPlayer() {
    "use strict";
    const players = [];
    let playerVars = {};
    let player = null;

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

    function onPlayerReady(event) {
        player = event.target;
        player.setVolume(100); // percent
    }

    let hasShuffled = false;

    function onPlayerStateChange(event) {
        player = event.target;
        if (!hasShuffled) {
            player.setShuffle(true);
            player.playVideoAt(0);
            hasShuffled = true;
        }

        if (event.data === YT.PlayerState.PLAYING) {
            players.forEach(function pauseOtherVideos(player) {
                if (player !== event.target) {
                    player.pauseVideo();
                }
            });
        }

        if (playerVars.loop && event.data === YT.PlayerState.ENDED) {
            player.seekTo(playerVars.start);
        }
    }

    function addPlayer(video, settings) {
        playerVars = Object.assign({
            host: "https://www.youtube-nocookie.com",
            videoId: video.dataset.id,
            events: {
                "onReady": onPlayerReady,
                "onStateChange": onPlayerStateChange
            }
        }, settings);
        players.push(new YT.Player(video, playerVars));

    }

    function play() {
        player.playVideo();
    }
    return {
        addPlayer,
        play
    };
}());

function loadPlayer(opts) {
    "use strict";

    function show(el) {
        el.classList.remove("hide");
    }

    function initPlayer(wrapper) {
        const video = wrapper.querySelector(".video");
        opts.width = opts.width || 198;
        opts.height = opts.height || 198;
        opts.autoplay = 0;
        opts.controls = 1;
        opts.rel = 0;
        opts.enablejsapi = 1;
        opts.iv_load_policy = 3;
        opts.fs = 0;
        opts.disablekb = 1;

        function paramInOpts(settings, param) {
            if (opts[param] !== undefined) {
                settings[param] = opts[param];
            }
            return settings;
        }
        const settingsParams = ["width", "height", "videoid", "host"];
        const settings = settingsParams.reduce(paramInOpts, {});
        const playerVarsParams = ["autoplay", "cc_load_policy",
            "controls", "disablekb", "end", "fs", "iv_load_policy",
            "list", "listType", "loop", "playlist", "rel", "start"
        ];
        settings.playerVars = playerVarsParams.reduce(paramInOpts, {});
        videoPlayer.addPlayer(video, settings);
    }

    function coverClickHandler(evt) {
        const wrapper = evt.currentTarget.nextElementSibling;
        show(wrapper);
        initPlayer(wrapper);
    }
    const cover = document.querySelector(opts.target);
    cover.addEventListener("click", coverClickHandler);
}
const playlist = "0dgNc5S8cLI,mnfmQe8Mv1g,-Xgi_way56U,CHahce95B1g";

function onYouTubeIframeAPIReady() {
    loadPlayer({
        height: 207,
        target: ".jacket-left",
        width: 277
    });
    loadPlayer({
        height: 207,
        start: 4,
        target: ".jacket-middle",
        width: 277
    });
    loadPlayer({
        height: 207,
        target: ".jacket-right",
        width: 277
    });
    loadPlayer({
        height: 338,
        loop: true,
        playlist,
        target: ".jacketc",
        width: 600
    });
    loadPlayer({
        end: 280,
        loop: true,
        start: 0,
        target: ".alpha"
    });
    loadPlayer({
        end: 240,
        loop: true,
        start: 0,
        target: ".beta"
    });
    loadPlayer({
        end: 265,
        loop: true,
        start: 0,
        target: ".gamma"
    });
    loadPlayer({
        end: 254,
        loop: true,
        start: 4,
        target: ".delta"
    });
    loadPlayer({
        end: 242,
        loop: true,
        start: 0,
        target: ".epsilon"
    });
    loadPlayer({
        end: 285,
        loop: true,
        start: 0,
        target: ".zeta"
    });
    loadPlayer({
        end: 312,
        loop: true,
        start: 23,
        target: ".eta"
    });
    loadPlayer({
        start: 2,
        target: ".theta"
    });
    loadPlayer({
        target: ".iota"
    });
}

All that is being done is I think, allowing the code to give settings and properties to multiple video players, for when there is more than one on the screen.

 initPlayer({
        height: 207,
        target: ".jacket-left",
        width: 277
    });
    initPlayer({
        height: 207,
        start: 4,
        target: ".jacket-middle",
        width: 277
    });
    initPlayer({
        height: 207,
        target: ".jacket-right",
        width: 277
    });
    initPlayer({
        height: 338,
        loop: true,
        playlist: "0dgNc5S8cLI,mnfmQe8Mv1g,-Xgi_way56U,CHahce95B1g",
        target: ".jacketc",
        width: 600
    });

Updated code:
https://jsfiddle.net/mLngcw37/

Working properly code:
https://jsfiddle.net/84jcb2xa/

You would have to I think look at the working properly code to figure out what needs to be changed in the updated code.