微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

'YT' 未定义 - Youtube Player API

如何解决'YT' 未定义 - Youtube Player API

我在我的 React 站点上使用 Youtube Player API。当我在网站上尝试时,它给出了这个错误TypeError: Cannot read property 'ready' of undefined。这是我正在使用的代码

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.com/iframe_api";
    var firstScriptTag = document.getElementsByTagName("script")[0];
    firstScriptTag.parentNode.insertBefore(tag,firstScriptTag);

    loadVideo();
  },[]);

内嵌框架:

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

(将代码编辑为最​​新的解决方法) 我怎样才能让它工作?

解决方法

您必须按照 documentation 的建议加载库。下面的代码异步加载库,然后库在准备就绪时通过全局 onYouTubeIframeAPIReady 回调(名称是必需的)“回调”您的代码。

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

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

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

在 YouTube 库代码中进行一些逆向工程时,我们可以看到这一行(我自己未缩小):

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

显示了这个函数是如何被调用的,以及为什么如果它不存在它不会抛出任何错误。


当我再次阅读您的问题时,您正在使用 React,因此之前的解决方案可能无法很好地集成,您可能不希望使用全局回调并使用它:

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

这个自定义钩子只会加载一次 YouTube 库,延迟加载(第一次需要)。您可以将它导入到需要它的每个组件中,并与 useYoutube(loadVideo) 一起使用。

这是一个有效的 Stackblitz demo

也适用于本地: enter image description here

,

对象显示在控制台中的原因是控制台与您的代码异步运行。当您遇到错误 YT 尚未加载,但在显示控制台时已经发生。

您可以证明这是更改控制台日志以使用 JSON.serialise() 将对象解析为字符串,然后该字符串将记录对象的运行时状态。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。