2
votes

I've just noticed that the Youtube events (onReady, onStateChange) are no longer firing when I am testing in my local, but works when I upload the code to JsFiddle. I've decided to copy and paste the code from Youtube Player API where I am able to verify that it indeed is not working. Is anyone else having this issue? This issue occurs on Chrome, Firefox, IE, Safari, and Opera.

EDIT - When I console.log(player); in my local, I see that it is missing a lot of Youtube functions such as seekTo(), setVolume(), showVideoInfo() which are present in JsFiddle. I am unsure why this is happening, but I believe this might be the root of my problem. Any ideas?

http://jsfiddle.net/8ZmKx/

<!DOCTYPE html>
<html>
  <body>
    <!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
    <div id="player"></div>

    <script>
      // 2. This code loads the IFrame Player API code asynchronously.
      var tag = document.createElement('script');

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

      // 3. This function creates an <iframe> (and YouTube player)
      //    after the API code downloads.
      var player;
      function onYouTubeIframeAPIReady() {
        player = new YT.Player('player', {
          height: '190',
          width: '140',
          videoId: 'M7lc1UVf-VE',
          events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange
          }
        });
      }

      // 4. The API will call this function when the video player is ready.
      function onPlayerReady(event) {
        console.log('ready');
        event.target.playVideo();
      }

      // 5. The API calls this function when the player's state changes.
      //    The function indicates that when playing a video (state=1),
      //    the player should play for six seconds and then stop.
      var done = false;
      function onPlayerStateChange(event) {
        console.log('change');
        if (event.data == YT.PlayerState.PLAYING && !done) {
          setTimeout(stopVideo, 6000);
          done = true;
        }
      }
      function stopVideo() {
        player.stopVideo();
      }
    </script>
  </body>
</html>
2

2 Answers

4
votes

It appears that the Youtube iframe API is currently broken, though I've seen no official confirmation yet.

See also:

onReady callback not firing when having the iframe explicitly written inside a template

YouTube API onPlayerReady not firing

Edit: Here is the fix: https://code.google.com/p/gdata-issues/issues/detail?id=5670#c6

Here is a direct quote of the answer at the link above:

A quick fix is to add in the origin=http://www.example.com (replace with your servers full domain; make sure you use http:// or https:// as appropriate for your site) to the src= attribute of the player's iframe element. Please make sure that the origin= attribute's value exactly matches the host domain and URL scheme. E.g.

<iframe
  type="text/html"
  width="640"
  height="480"
  src="https://www.youtube.com/embed/VIDEO_ID?enablejsapi=1&origin=https://www.example.com"
  frameborder="0">
</iframe>

I'm currently working with the engineering team to figure out whether origin= is going to be required moving forward or whether this new requirement can be reverted, but this is the immediate fix. Apologies for the breakage and lack of advanced communication in the meantime.

If you use the YT.Player() constructor to create the iframe element for you then this isn't be an issue—it's a bit of an edge case for developers who are explicitly including the iframe element as part of their page's HTML.

I implemented the fix above, and it worked for me.

1
votes

I had put in a fix that implemented the "origin=" param, fixing the original bug and firing state change events.

Now having that origin param is causing the bug. Removed the param, and it works again.