Youtube iframe api not triggering onYouTubeIframeA

2019-01-07 13:06发布

I've been battling with the youtube iframe api for quite some time now. Somehow the method onYouTubeIframeAPIReady is not always triggered.

From the symptoms it seems a loading problem. No errors are shown in the inspector.

Here is my code:

HTML

<div id="player"></div>
          <script>
            videoId = 'someVideoId';
            var tag = document.createElement('script');
            tag.src = "//www.youtube.com/iframe_api";
            var firstScriptTag = document.getElementsByTagName('script')[0];
            firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
          </script>

JS

(called at the end of the page. I tried to place the code right after the above script and the result was the same.)

var isReady = false
  , player
  , poster
  , video;

$(function () {
$('.js-play').click(function (e) {
    e.preventDefault();
    interval = setInterval(videoLoaded, 100);
  });
});
function onYouTubeIframeAPIReady() {
  console.log(videoId)
  player = new YT.Player('player', {
    height: '445',
    width: '810',
    videoId: videoId,
    events: {
      'onReady': onPlayerReady//,
      //'onStateChange': onPlayerStateChange
    }
  });
}

function onPlayerReady(event) {
  isReady = true;
  console.log("youtube says play")
}

function videoLoaded (){
  if (isReady) {
      console.log("ready and play")
      poster.hide();
      video.show();

      $('body').trigger('fluidvideos');

      player.playVideo();
      clearInterval(interval);
  } 
}

The problem is that sometimes nothing gets printed by the console.log and nothing happens.

On mobile phones this happens all the time. Any ideas?

9条回答
对你真心纯属浪费
2楼-- · 2019-01-07 13:35

I actually made this to lazy load the youtube player. Seems bullet proof to me.

window.videoApiLoaded = [];
window.videoApiLoaded.youtube = false;

function loadYoutubeVideo(videoId) {

    window.onYouTubeIframeAPIReady = function() { document.dispatchEvent(new CustomEvent('onYouTubeIframeAPIReady', {})) };

    if(window.videoApiLoaded.youtube == false) {
        var tag = document.createElement('script');
        tag.src = "https://www.youtube.com/iframe_api";
        var firstScriptTag = document.getElementsByTagName('script')[0];
        firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
        window.videoApiLoaded.youtube = true;
    }

    var player;

    document.addEventListener('onYouTubeIframeAPIReady', function (e) {
        player = new YT.Player('player', {
          height: '400',
          width: '600',
          videoId: videoId,
          events: {
            'onStateChange': onYtStateChange
          }
        });

    }, false);

}
查看更多
够拽才男人
3楼-- · 2019-01-07 13:46

It is not a timeout issue, and you should not need to fire this function manually.

Make sure your onYouTubeIframeAPIReady function is available at the global level, not nested (hidden away) within another function.

查看更多
闹够了就滚
4楼-- · 2019-01-07 13:48

If you load the IFrame Player API code asynchronously as follows:

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

and you are also loading the script code like this:

<script src="http://www.youtube.com/player_api"></script>

then the function onYouTubeIframeAPIReady won't be called due to the same code is being loaded twice (the function is called just one time when the api is completely loaded).

So use just one of the ways according to your needs.

查看更多
霸刀☆藐视天下
5楼-- · 2019-01-07 13:51

You can always append it to the window object to make sure it is evoked globally. This is helpful if your code is using amd.

window.onYouTubeIframeAPIReady = function() {}
查看更多
男人必须洒脱
6楼-- · 2019-01-07 13:53

I had a similar problem, In my case onYouTubeIframeAPIReady was being called so fast that the actual implementation wasn't ready for the right call. So after youtube player_api call I added a simple implementation with a var for verification of onYouTubeIframeAPIReady just like that:

<script src="http://www.youtube.com/player_api"></script>
<script>
var playerReady = false
window.onYouTubeIframeAPIReady = function() { //simple implementation
    playerReady = true;
}
</script>
</header>
.
.
.
<body>
<script>
window.onYouTubeIframeAPIReady = function() { //real and fully implemented
    var player; // ... and so on ...
}
if(playerReady) { onYouTubeIframeAPIReady(); console.log("force to call again") }
</script>
查看更多
乱世女痞
7楼-- · 2019-01-07 13:56

Make sure you are testing the page by having it actually served on the web, not just loaded locally. YouTube iFrame API behavior is inconsistent/nondeterministic

查看更多
登录 后发表回答