playVideo() in YouTube code not working how it should Help!

When you click on the red play the video starts playing right away. You can hear the music and everything.

Red Play after Click

When you click on the blue play the video doesn’t start playing. The video does not start and there is no music playing.

There’s No audio, and there is no music playing after clicking on the blue play. The video should start playing right after clicking on the blue play. That’s exactly how it works on the red play.

Blue Play after Click

Clicking on the Blue play should work exactly the same as clicking on the Red play.

After clicking on the Red play, the video starts playing right away.

After clicking on the Blue play, the video does not start playing.

Click Run not update to test code.

https://jsitor.com/_IFtULGxPP

Can someone see if they are able to figure this out.

How would I be able to get the 2nd video to start playing when it is clicked on?

It should work the same as clicking on the Red play.

In the code, Both the Red & Blue play use .thePlay as a class.

What would need to be adjusted or changed in the code for it to be working as it should?

This is The Flow of It:

For some reason it is only allowing the 1st .thePlay class to play on click, the 2nd .thePlay video class doesn’t start when you click on it. Meaning, the video doesn’t start playing.

It goes from here:

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

To Here:

function onYouTubeIframeAPIReady() {
 const cover = document.querySelector(".thePlay");
 const wrapper = cover.parentElement;
 const frameContainer = wrapper.querySelector(".video");
 videoPlayer.addPlayer(frameContainer);

To Here:

(function initCover() {

 function coverClickHandler() {
   videoPlayer.play();
 }

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

Full Code:

const manageCover = (function makeManageCover() {
 const config = {};

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

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

 function hideAll(elements) {
   elements.forEach(hide);
 }

 function showCovers(playButton) {
   const cover = playButton.parentElement;
   cover.classList.add("active");
   show(cover);
 }

 function coverClickHandler(evt) {
   hideAll(config.containers);
   const cover = evt.currentTarget;
   showCovers(cover);
 }

 function addClickToButtons(playButtons) {
   playButtons.forEach(function addEventHandler(playButton) {
     playButton.addEventListener("click", coverClickHandler);
   });
 }

 function addCoverHandler(coverSelector, handler) {
   const cover = document.querySelector(coverSelector);
   cover.addEventListener("click", handler);
 }

 function init(selectors) {
   config.containers = document.querySelectorAll(selectors.container);
   const playButtons = document.querySelectorAll(selectors.playButton);
   addClickToButtons(playButtons);
 }

 return {
   addCoverHandler,
   init,
   show
 };
}());

const videoPlayer = (function makeVideoPlayer() {
 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);

 }

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

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

const managePlayer = (function makeManagePlayer() {
 const defaults = {
   height: 600,
   width: 360
 };
 defaults.playerVars = {
   controls: 1,
   disablekb: 1,
   enablejsapi: 1,
   fs: 0,
   iv_load_policy: 3,
   rel: 0
 };

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

 function createPlayerOptions(settings) {
   function paramInOptions(opts, param) {
     if (settings[param] !== undefined) {
       opts[param] = settings[param];
       delete settings[param];
     }
     return opts;
   }

   const optionParams = ["width", "height", "videoid", "host"];
   const preferred = optionParams.reduce(paramInOptions, {});
   const playerOptions = Object.assign({}, defaults, preferred);
   // settings should now only consist of playerVars
   const playerVars = Object.assign({}, defaults.playerVars, settings);
   playerOptions.playerVars = playerVars;
   return playerOptions;
 }

 function createPlayer(videoWrapper, settings = {}) {
   const video = videoWrapper.querySelector(".video");
   const playerOptions = createPlayerOptions(settings);
   return videoPlayer.addPlayer(video, playerOptions);
 }

 function createCoverClickHandler(playerSettings) {
   return function coverClickHandler(evt) {
     const cover = evt.currentTarget;
     const wrapper = cover.nextElementSibling;
     show(wrapper);
     const player = createPlayer(wrapper, playerSettings);
     wrapper.player = player;
   };
 }

 function addPlayer(coverSelector, playerSettings) {
   const clickHandler = createCoverClickHandler(playerSettings);
   manageCover.addCoverHandler(coverSelector, clickHandler);
 }

 return {
   add: addPlayer
 };
}());
function onYouTubeIframeAPIReady() {
 const cover = document.querySelector(".thePlay");
 const wrapper = cover.parentElement;
 const frameContainer = wrapper.querySelector(".video");
 videoPlayer.addPlayer(frameContainer);

 managePlayer.add(".playa", {
   height: 207,
   start: 4,
   width: 277
 });
 managePlayer.add(".playb", {
   height: 207,
   width: 277
 });
 manageCover.init({
   container: ".container",
   playButton: ".thePlay"
 });
}
(function initCover() {

 function coverClickHandler() {
   videoPlayer.play();
 }

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

HTML

<div class="outer">
	<div class="container with-curtain">
		<svg class="playa thePlay" width="100%" height="100%" viewBox="0 0 64 64">
			<path d="M25.6,46.4L44.8,32L25.6,17.6V46.4z M32,0C14.3,0,0,14.3,0,32s14.3,32,32,32s32-14.3,32-32S49.7,0,32,0z
      M32,57.6C17.9,57.6,6.4,46.1,6.4,32S17.9,6.4,32,6.4S57.6,17.9,57.6,32S46.1,57.6,32,57.6z" />
		</svg>
		<div class="inner-container curtain curtain1">
			<div class="ratio-keeper">
				<div class="wrapa">
					<div class="video video-frame" data-id="qe5WF4qCSkQ"></div>
				</div>
				<div class="panel-left"></div>
				<div class="panel-right"></div>
			</div>
		</div>
	</div>
	<!-- end container -->
	<div class="container with-curtain">
		<svg class="playb thePlay " width="100%" height="100%" viewBox="0 0 64 64">
			<path d="M25.6,46.4L44.8,32L25.6,17.6V46.4z M32,0C14.3,0,0,14.3,0,32s14.3,32,32,32s32-14.3,32-32S49.7,0,32,0z
      M32,57.6C17.9,57.6,6.4,46.1,6.4,32S17.9,6.4,32,6.4S57.6,17.9,57.6,32S46.1,57.6,32,57.6z" />
		</svg>
		<div class="inner-container curtain curtain2">
			<div class="ratio-keeper">
				<div class="wrapa">
					<div class="video video-frame" data-id="2VwsvrPFr9w"></div>
				</div>
				<div class="panel-left"></div>
				<div class="panel-right"></div>
			</div>
		</div>
	</div>
</div>

Hi javascriptcoding5678,

could you explain or link the code challenge that you are working on?

best,
Dennis

Is there anyone who can help me resolve this issue I am having?

What needs to be adjusted in the code?

I updated the topic post at the top.

I provided more information on the issue I am trying to fix.

The root of the problem is this (line 178):

const cover = document.querySelector(".thePlay");

You have two play buttons, both with a class of .thePlay. But using querySelector, it’ll only select the first of both buttons. Instead you want querySelectorAll(.thePlay), which will give you a list of all play buttons, not just the first one.

That’s all I can say. You’ll need adjustments to account for this at various places.

1 Like

I changed this:

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

to this:
https://jsitor.com/Thscd45Up

  const covers = document.querySelectorAll(".thePlay");
  covers.forEach(function addHandler(cover) {
    cover.addEventListener("click", coverClickHandler);
  });
}());

I think I would need to change this one also, but I don’t know how.

function onYouTubeIframeAPIReady() {
  const cover = document.querySelector(".thePlay");
  const wrapper = cover.parentElement;
  const frameContainer = wrapper.querySelector(".video");
  videoPlayer.addPlayer(frameContainer);

Doing this gives me:
const cover = document.querySelectorAll(".thePlay");

Uncaught TypeError: Cannot read property ‘querySelector’ of undefined at line 154 col 34

Line 154
const frameContainer = wrapper.querySelector(".video");

Are you sure .parentElement found the one you expect? According to that error message, it did not. console.log(wrapper) to see what it contains.

It contains this?

I should change
const wrapper = cover.parentElement;

to this?
const wrapper = cover.nextElementSibling;

That change, is reflected here:
https://jsitor.com/dq-gM1WpeJ


function onYouTubeIframeAPIReady() {
  const cover = document.querySelector(".thePlay");
  const wrapper = cover.nextElementSibling;
  const frameContainer = wrapper.querySelector(".video");
  videoPlayer.addPlayer(frameContainer);

I still have to change:
const cover = document.querySelector(".thePlay");

to:
const covers = document.querySelectorAll(".thePlay");

Right?

Seems you’re randomly poking attributes, hoping to find the wrapper in one of them.

Is the wrapper a container of cover? Does it have any distinguishing classes of it’s own?

1 Like

Yes, the wrapper is the container of the cover.

And wrapper is used 6 times in the javascript.

const wrapper = cover.nextElementSibling;
      show(wrapper);
      const player = createPlayer(wrapper, playerSettings);
      wrapper.player = player;
  const wrapper = cover.nextElementSibling;
  const frameContainer = wrapper.querySelector(".video");

What was I supposed to be looking for when I did this?
console.log(wrapper)

append:
appendChild:

If the wrapper is the container of the cover, then how can it be a sibling of the cover as well? That would be akin to you being your own son.

The wrapper is not a sibling of the cover. It’s not in the html or css at all.

Then doing any sort of parentElement or nextSibling will fail. Every time.

1 Like

What would it be replaced with?

Someone had asked in the past, and I don’t know if you’d answered - which freecodecamp lesson or project is this related to?

This isn’t a lesson it’s a project I am working on.

Is that the reason why the video isn’t playing after the blue play is clicked?

both buttons play a video when I click on them. Not sure what behavior you’re seeing.

After the blue play is clicked, the video is not playing, look at the images at the top that I posted.

https://jsitor.com/dq-gM1WpeJ

After clicking the Red Play, the video starts playing right away.

After clicking the Blue Play the video does not start playing at all.

That is the issue I am trying to fix.

Clicking on the Blue play should be the same as the red.