最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

javascript - 'YT' is not defined - Youtube Player API - Stack Overflow

matteradmin6PV0评论

I am using Youtube Player API on my React site. When I try it on the site, it gives this error: TypeError: Cannot read property 'ready' of undefined. Here is the code I am using:

var player;
function loadVideo() {
    window.YT.ready(function () {
      new window.YT.Player("player", {
        height: "390",
        width: "640",
        videoId: "M7lc1UVf-VE",
        events: {
          onReady: onPlayerReady,
          onStateChange: onPlayerStateChange,
        },
      });
    });

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

    function onPlayerStateChange(event) {
      var videoStatuses = Object.entries(window.YT.PlayerState);
      console.log(videoStatuses.find((status) => status[1] === event.data)[0]);
    }
  }

  useEffect(() => {
    setMaxDuration("06:00");
    var tag = document.createElement("script");
    tag.src = ";;
    var firstScriptTag = document.getElementsByTagName("script")[0];
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

    loadVideo();
  }, []);

Iframe:

  <div id="player">
    <iframe
      title="p"
      id="player"
      width="560"
      height="315"
      src=";autoplay=1"
      frameBorder="0"
      allowFullScreen
    ></iframe>
  </div>

(edited the code to the latest workaround) How can I get this to work?

I am using Youtube Player API on my React site. When I try it on the site, it gives this error: TypeError: Cannot read property 'ready' of undefined. Here is the code I am using:

var player;
function loadVideo() {
    window.YT.ready(function () {
      new window.YT.Player("player", {
        height: "390",
        width: "640",
        videoId: "M7lc1UVf-VE",
        events: {
          onReady: onPlayerReady,
          onStateChange: onPlayerStateChange,
        },
      });
    });

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

    function onPlayerStateChange(event) {
      var videoStatuses = Object.entries(window.YT.PlayerState);
      console.log(videoStatuses.find((status) => status[1] === event.data)[0]);
    }
  }

  useEffect(() => {
    setMaxDuration("06:00");
    var tag = document.createElement("script");
    tag.src = "https://www.youtube./iframe_api";
    var firstScriptTag = document.getElementsByTagName("script")[0];
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

    loadVideo();
  }, []);

Iframe:

  <div id="player">
    <iframe
      title="p"
      id="player"
      width="560"
      height="315"
      src="https://www.youtube./embed/sGPrx9bjgC8&autoplay=1"
      frameBorder="0"
      allowFullScreen
    ></iframe>
  </div>

(edited the code to the latest workaround) How can I get this to work?

Share Improve this question edited May 12, 2021 at 10:35 Guerric P 31.9k6 gold badges58 silver badges106 bronze badges asked May 1, 2021 at 7:02 Ajit KumarAjit Kumar 4171 gold badge14 silver badges39 bronze badges 4
  • Is this script supposed to create a YT global variable? – T J Commented May 1, 2021 at 7:05
  • I think it is. I followed this guide: developers.google./youtube/iframe_api_reference – Ajit Kumar Commented May 1, 2021 at 7:06
  • window.YT.Player(...) – dbuchet Commented May 11, 2021 at 13:16
  • 1 Now your problem is solved I reverted your question, according to this: meta.stackoverflow./questions/377812/… In general your question can evolve with debugging details but should not pletely change. Your question will be more useful in its original state for future users that encounter the same problem. And we can discuss about my answer in the ments or in the chat instead of editing the question with its content – Guerric P Commented May 12, 2021 at 10:54
Add a ment  | 

2 Answers 2

Reset to default 5 +50

You have to load the library as suggested by the documentation. The code below loads the library asynchronously, then the library "calls back" your code when ready via the global onYouTubeIframeAPIReady callback (the name is mandatory).

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

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

function onYouTubeIframeAPIReady() {
  console.log('Yay, YT exists!', YT);
}

When doing a bit of reverse engineering in the YouTube library code we can see this line (unminified by myself):

const callback = window.onYouTubeIframeAPIReady;
callback && callback();

Which shows how this function is being called and why it doesn't throw any error if it doesn't exist.


As I read your question again, you're using React, so the previous solution might not integrate very well, you might prefer not to use the global callback and use this instead:

const useYoutube = callback => {
  useEffect(() => {
    if (!window.YT) {
      var tag = document.createElement('script');
      tag.src = 'https://www.youtube./iframe_api';
      var firstScriptTag = document.getElementsByTagName('script')[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
      tag.onload = callback;
    } else {
      callback();
    }
  }, []);
};

This custom hook will load the YouTube library only once, lazily (the first time it is needed). You could import it in every ponent that needs it, and use it with useYoutube(loadVideo).

Here is a working Stackblitz demo

Works also in local:

The reason the the object shows up in the console, is that the console runs asynchronously from you code. When you have the error YT is not yet loaded, but it has been by the time the console is displayed.

You can prove this be changing your console log to parse the object into a string with JSON.serialise() which will then log the runtime state of the object.

Post a comment

comment list (0)

  1. No comments so far