【问题标题】:YouTube API not loading consistentlyYouTube API 加载不一致
【发布时间】:2019-06-02 09:24:11
【问题描述】:

对于我工作的大学,我正在尝试让一个 youtube 视频在网页的横幅中自动播放。 API 并非每次都正确加载。我不确定我能做些什么来解决这个问题。

我试过了:

  • 仅在 DOM 准备好时才添加 youtube API 脚本。

  • 将代码放在页面的顶部和底部。

  • 检查播放器对象是否创建正确,如果没有尝试重新创建它,我了解到会破坏 API。

如果我剥离所有页面并仅使用横幅,则视频加载的频率更高,但仍不是 100% 的时间。

在这里,我在通过 YouTube API 加载视频的页面上提供了脚本。

更新: 从我通过登录控制台可以看出,播放器对象没有被完全初始化。 当它没有正确创建时,这就是对象打印出来的样子:

Y {b: null, a: null, h: null, closure_uid_165988549: 1, g: 1, …}

这是正确完成的时间:

Y {b: Wa, a: iframe#ytplayer, h: div#ytplayer, closure_uid_16195269: 1, g: 1, …}

我错了,没有找到 videoId。每次调用函数之前都会设置视频,因此这应该不是问题。

<div id="ytplayer"></div>

  <script>
    defer(function() {if(window.mobile === true) { $('#ytplayer').remove(); }});
     var ready;
    // Replace the 'ytplayer' element with an <iframe> and
    // YouTube player after the API code downloads.
    var player;
    // var videoId = 'ZCESafUzSRo';
  function onYouTubeIframeAPIReady() {
      checkFunction();
    }

    function checkFunction() {
      console.log("checkFunction called");
      setYTready(ready);
    }
    function setYTready(ready) {
      console.log("setYT ready called");
      ready = true;
      mtuPlayerCreate(player);
    }

    function mtuPlayerCreate(player) {
      console.log("mtu create called");



      if((player == undefined) && ( document.getElementById("play-yt") != null)) {
    console.log("Creating player");
      player = new YT.Player('ytplayer', {
        height: '52.65%',
        width: '100%',
        playerVars: {
          'controls': 0,
          'showinfo': 0,
          'rel': 0,
          'iv_load_policy': 3
        },
        videoId: videoId,
        events: {
          'onReady': onPlayerReady,
          // Removing the following if loop shouldn't be enabled
          onStateChange: 
          function(e){
            if (e.data === YT.PlayerState.ENDED) {
              player.playVideo(); 
            }
          }
        }
      });

    }
    console.log("player redo below");
    console.log(player);
      if(player.A == false) {
      //setTimeout(function() {location.reload();}, 2000); 
    } else {
      return;
    }
  }


    function onPlayerReady(event) { /* configuring default playing and mute settings */
      console.log("on ready has been called")
      var autoPlay = 1;
      var autoMute = 1;
      if(autoPlay === 1) { event.target.playVideo(); }
      if(document.getElementById('play-yt') && autoPlay === 1) { document.getElementById('play-yt').className = 'pause'; }else if(document.getElementById('play-yt')) { document.getElementById('play-yt').className = 'play'; }
      if(autoMute === 1) { event.target.mute(); }
      if(document.getElementById('mute-yt') && autoMute === 1) { document.getElementById('mute-yt').className = 'mute'; }else if(document.getElementById('mute-yt')) { document.getElementById('mute-yt').className = 'loud'; }
      if(document.getElementById('yt-yt')) { document.getElementById('yt-yt').className = ''; }
    }

    window.onload = function() { /* this handles what happens when the player and its buttons are clicked on */

            document.getElementsByClassName('media-black')[0].onclick=function(e) { 
        if(e.target.id !== 'yt-yt' && e.target.id !== 'mute-yt') {
          if(player.getPlayerState() === -1 || player.getPlayerState() === 2  || player.getPlayerState() === 5) {  
            player.playVideo(); 
            if(document.getElementById('play-yt')) { document.getElementById('play-yt').className = 'pause'; }
            if (window._gaq) _gaq.push(['_trackEvent', 'Wide Video', 'Played', window.location.href]);
          }else{
            player.pauseVideo(); 
            if(document.getElementById('play-yt')) { document.getElementById('play-yt').className = 'play'; }
            if (window._gaq) _gaq.push(['_trackEvent', 'Wide Video', 'Paused', window.location.href]);
          }
        }
        else if(e.target.id === 'yt-yt' && e.target.id !== 'mute-yt') {
          window.open('http://www.youtube.com/watch?v=' + videoId, '_blank');
          player.pauseVideo();
          if(document.getElementById('play-yt') && document.getElementById('play-yt').className === 'pause') { document.getElementById('play-yt').className = 'play'; }
          if (window._gaq) _gaq.push(['_trackEvent', 'Wide Video', 'Went to YouTube', window.location.href]);
        }else{
          if(player.isMuted() || player.getVolume() === 0) { player.unMute(); player.setVolume(100); document.getElementById('mute-yt').className = 'loud'; }else{ player.mute(); document.getElementById('mute-yt').className = 'mute'; }
          if (window._gaq) _gaq.push(['_trackEvent', 'Wide Video', 'Sound Adjusted', window.location.href]);
        }
      };



    }

    //
    //This could be improved, test if it's mobile and load if not instead of loading and then removing if mobile
    //
    // Load the IFrame Player API code asynchronously.
    document.addEventListener("DOMContentLoaded", function(event) { 
      console.log("dom ready!");
    var tag = document.createElement('script');
    tag.src = "https://www.youtube.com/player_api";
  var firstScriptTag = document.getElementsByTagName('script')[0];
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
  });
  </script> 
</div>

它需要做的是:

  1. 加载 API
  2. 加载具有给定视频 ID 的播放器对象
  3. 将 iframe 添加到正确的位置
  4. 自动播放视频。

每次页面加载时都需要这样做。

【问题讨论】:

  • 您能否扩展“API 每次都未正确加载”?发生了什么?开发控制台/网络选项卡未加载时是否有任何错误?
  • 我认为播放器对象加载了视频 ID 的空值。没有抛出错误。我能够通过将播放器对象打印到开发控制台来解决这个问题。我认为正在发生的是,由于将代码加载到页面时出现同步问题,它找不到视频 ID。从而导致由 youtube API 创建的 iframe 加载一个空视频。在测试时,它有时会加载正确的视频,有时不会。这可能是 youtube API 的问题。
  • 您从哪里获得videoId?你在硬编码吗?
  • 是的,它被硬编码到代码中。它被设置在网页的标题中。这些页面是通过 OU 校园生成的,它使用 XSLT 生成页面的 html。视频 id 是页面的参数,这就是它存在的原因。这是设置它的代码。 code:&lt;section id="media" title="Aerial view of the Michigan Tech campus." aria-label="Aerial view of the Michigan Tech campus." style="background-image: url('/about/images/campus-1600feature.jpg')" class="jumbo video"&gt;&lt;script type="text/javascript"&gt;var videoId = 'kED0mcZuifU';&lt;/script&gt;&lt;div id="videoWrapper"&gt;

标签: javascript jquery youtube youtube-api


【解决方案1】:

我不确定您为什么要以这种方式加载 YouTube iframe 播放器,但是,我通过修改您的代码制作了这个 jsfiddle - 并且 YouTube 播放器 iframe 可以正常工作。

这些是我所做的修改——你可以在修改后的代码中找到更多的 cmets:

  • 我评论了 mtuPlayerCreate 行 - 您是否要添加另一个 YouTube iframe?
  • 添加 onPlayerStateChange 函数以设置 HTML 元素的功能 - 能够控制 iframe - “播放/暂停,(取消)静音视频”
  • controls 的值为 0,我将其设置为 1 以检查它是否通过单击 HTML 元素正确控制 YouTube iframe。

这是jsfiddle 代码:

// No need for replace the elemnt - YouTube Iframe Player will load in this object and HTML element:
var player;

// This is your videoId "you had it commented".
// it was the video is not available:
//var videoId = 'ZCESafUzSRo';

// Video: "Microsoft Windows Mixed Reality update | October 2018" - by Microsoft Hololens.
var videoId = '00vnln25HBg';

// Check whether iframe is mute.
var isUnMuted = false;

// Here, the YouTube Player API will build the iframe in the "ytplayer" HTML element
// and in the "player" variable.
function onYouTubeIframeAPIReady() {
  player = new YT.Player('ytplayer', {
    height: '52.65%',
    width: '100%',
    playerVars: {
      'controls': 1, 
      'showinfo': 1,
      'rel': 0,
      'iv_load_policy': 3,
      'autoplay': 1,
      'loop': 1,
    },
    videoId: videoId,
    events: {
      'onReady': onPlayerReady,
      'onStateChange': onPlayerStateChange
    }
  });

  // After loading the iframe, set the "playVideo" onclick event on "playButton" anchor element.
  document.getElementById('play-yt').onclick = function() {
    player.playVideo();
  };

  // Thanks to this answer, here you can check the status of "mute" - I culdn't make it work, in the "onPlayerStateChange" function though.
  // Source: https://stackoverflow.com/a/36436765/4092887
  document.getElementById('mute-yt').innerHTML = 'MUTE';
  document.getElementById('mute-yt').onclick = function() {
    player.mute();
  };

  document.getElementById('yt-yt').innerHTML = 'UNMUTE';
  document.getElementById('yt-yt').onclick = function() {
    player.unMute();
  };

}

function checkFunction() {
  console.log("checkFunction called");
  setYTready(ready);
}

function setYTready(ready) {
  console.log("setYT ready called");
  // Not sure what you're doing here = do you want load another youtube iframe?
  //mtuPlayerCreate(player);
}

function mtuPlayerCreate(player) {
  console.log("mtu create called");



  if ((player == undefined) && (document.getElementById("play-yt") != null)) {


  }
  console.log("player redo below");
  console.log(player);
  if (player.A == false) {
    //setTimeout(function() {location.reload();}, 2000); 
  } else {
    return;
  }
}

/* configuring default playing and mute settings */
/* You only need set here the following line: */
function onPlayerReady(event) {
  event.target.playVideo();
}

/* this handles what happens when the player and its buttons are clicked on */
/* You can do it in this way instead: */
function onPlayerStateChange(e) {
  // Removing the following if loop shouldn't be enabled.
  // This is for emulate "loop" functionality.
  if (e.data === YT.PlayerState.ENDED) {
    player.playVideo();
  }

  // If the video is PLAYING, set the onclick element for pause the video.
  // Once the "playButton" is clicked, the video will be paused.
  if (e.data == YT.PlayerState.PLAYING) {
    document.getElementById('play-yt').innerHTML = 'PAUSE';
    document.getElementById('play-yt').onclick = function() {
      player.pauseVideo();
    };
  }

  // If the video is PAUSED, set the onclick element for pause the video.
  // Once the "playButton" is clicked, the video will resume the video = continue playing the video.
  if (e.data == YT.PlayerState.PAUSED) {
    document.getElementById('play-yt').innerHTML = 'PLAY';
    document.getElementById('play-yt').onclick = function() {
      player.playVideo();
    };
  }

}

//
//This could be improved, test if it's mobile and load if not instead of loading and then removing if mobile
//
// Load the IFrame Player API code asynchronously.
document.addEventListener("DOMContentLoaded", function(event) {
  console.log("dom ready!");
  var tag = document.createElement('script');
  tag.src = "https://www.youtube.com/player_api";
  var firstScriptTag = document.getElementsByTagName('script')[0];
  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<div id="ytplayer"></div>

<p>
  <div>
    <span>Control your Youtube Iframe Player:</span>
  </div>

  <div id="play-yt">PLAY</div>
  <div id="mute-yt">MUTE</div>
  <div id="yt-yt">UNMUTE</div>
</p>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-12
    • 1970-01-01
    • 2013-08-10
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 2014-01-26
    相关资源
    最近更新 更多