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

When I click the blue button, the curtain effect on the image occurs, and the second video is displayed… but the first video is being played. The first video is hidden, so you see the second one displayed with a “play” button, but the first video is playing (I can hear its audio). Does this indicate something to you?

What do you think videoPlayer contains? When you click on either cover, it triggers videoPlayer.play() - but it seems that both videos play the same video. They may display different items when the image-curtain effect occurs, but they are playing the same video player.

Test this one:
https://jsitor.com/_IFtULGxPP

(function initCover() {

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

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

This was giving audio on the blue from the 1st video that you were hearing:
https://jsitor.com/dq-gM1WpeJ


(function initCover() {

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

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

In that one, that particular event listener has not been attached to the blue button. I can see two attached there, the ones to open the curtain and to display the cover… but the player action doesn’t attach to that second button.

Open your dev tools, and look at that button in the Elements inspector panel. On the right side of your devtools>Elements, you should see Event Listeners - letting you see the actual listeners attached to your element. In the last one you shared, the blue button had three listeners, though one pointed to the wrong video player. In this one, the blue button has two - lacking the player.

I would be fixing this one?
https://jsitor.com/_IFtULGxPP

1st

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

Or this one?
https://jsitor.com/dq-gM1WpeJ

2nd

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

As was said earlier - the first one only sees the first .thePlay element. If you only have one play button, then that works fine. But as you have multiple, it seems that won’t do what you want.

1 Like

https://jsitor.com/l0Bs7ffeX9

  const coversSelector = ".playa, .playb";
  const covers = document.querySelectorAll(coversSelector);
  covers.forEach(function (cover) {
    cover.addEventListener("click", coverClickHandler);
  });
}());

Next, how do I change this to:

function onYouTubeIframeAPIReady() {
  const cover = document.querySelector(".thePlay");

To this?
const cover = document.querySelectorAll(".playa, .playb");

I have no idea. I have never worked with the YouTube API, and I wouldn’t even know where to begin.

When this is set to this clicking on the blue play causes the video to start playing.

See
https://jsitor.com/xCdY7ePuhw

function onYouTubeIframeAPIReady() {
  const cover = document.querySelector(".playb");

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

This would need to be able to accept .playa, .playb

function onYouTubeIframeAPIReady() {
  const cover = document.querySelectorAll(".playa, .playb");

Do I add a forEach in there?

Do you think that’s where the problem resides? I have my doubts.

If you do the forEach, as you have elsewhere, how are you telling the videoPlayer which video to play?

I don’t know then.

I just know:

This works to play the 2nd video.
const cover = document.querySelector(".playb");

And this works to play the 1st video.
const cover = document.querySelector(".playa");

And this works to play only the 1st video.
const cover = document.querySelector(".thePlay");

I don’t know how to change this to All.
const cover = document.querySelectorAll("");

I keep getting this error when I try:

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

It looks like you are cannibalising code you find in the hopes of making this idea work. I strongly believe that you would benefit greatly from learning about fundamental principles from courses or tutorials.

1 Like

Making Progress:

When you click on the Red play, the video from the Blue play starts playing.

Sometimes no video is playing, and you can hear the video from the Blue play, or the other way around.

How it should work

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

After clicking on the Blue play, the video to the blue starts playing right away.

How would I be able to get this to work properly?

I am having difficulty trying to figure this out.

When testing the codes, Click Run not update

To reproduce issue, click either the Red play or the Blue play.

Click Run to reset then do it again.

1st Attempt

https://jsitor.com/3zP6EDApl

function onYouTubeIframeAPIReady() {
  const cover = document.querySelectorAll(".playa, .playb");console.log(cover);
  cover.forEach(function (cover) {
    const wrapper = cover.parentElement;
    const frameContainer = wrapper.querySelector(".video");
    videoPlayer.addPlayer(frameContainer);

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

2nd Attempt

https://jsitor.com/u1HXDKHOP

function onYouTubeIframeAPIReady() {
  const cover = document.querySelectorAll(".playa, .playb");console.log(cover);
  cover.forEach(function (cover) {
    const wrapper = cover.parentElement;
    const frameContainer = wrapper.querySelector(".video");
    videoPlayer.addPlayer(frameContainer);

  const covers = document.querySelectorAll("svg.playa, svg.playb");
  covers.forEach(function (cover) {
    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>

    <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>

I was just told this:

Your problem lies here
Think about what this does:

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

and what player will be once both videos are ready
and what that means for:

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

player is never swapped to the player represented by the play button
it’s always the last one that initialized
it’s also not safe to assume the players will always be ready in the same order
and… unless you intend to let multiple videos play at once, you probably don’t need two

Updated Code:

No jslint errors
https://jsitor.com/OnDaeEcxa

https://jsfiddle.net/x6t03uqc/

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 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);
        player.playVideo();
    }

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

    return {
        addPlayer

    };
}());

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

    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 defaultOptions = defaults.playerOptions;
        const preferred = optionParams.reduce(paramInOptions, {});
        const playerOptions = Object.assign({}, defaultOptions, preferred);
        // settings should now only consist of playerVars
        const defaultPlayerVars = defaultOptions.playerVars;
        const playerVars = Object.assign({}, defaultPlayerVars, 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);
    }

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

    return {
        add: addPlayer,
        init
    };
}());

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

In Video Code 1, after the play image is clicked, there’s a pause that is clearly visible.

In the YouTube image provided at the bottom, a pause is clearly viewable.

In Video Code 2, after the play image is clicked, there is no pause.

In the image provided down at the bottom, a pause is clearly not visible.

These are the play images that are clicked, then a video appears.

How do I get Video Code 1 to play the same way as Video Code 2?

Where there is no pause visible after clicking the play image?

What part of the code would need to be changed, and how would it be written into the code?

How would I add code that is in Video Code 2 to Video Code 1?

Click Run, not update to test code.

Video Code 1 https://jsitor.com/2DCwjO_DJC

Code Uses:

  function onPlayerReady(event) {
    player = event.target;
    player.playVideo();
  }

Video Code 2 https://jsitor.com/-DZ-97-jCB

This is exactly how Video Code 1 should work, where there is no pause that is visible.

Code Uses:

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

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

(function initCover() {

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

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

Video Code 1 Do you see the pause visible?

After clicking the play image I see this.

Video Code 2 There is no pause able to be seen here.

After clicking the play image I see this.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.