javascript - YouTube iFrame API behavior is inconsistentnondeterministic - Stack Overflow

I was having trouble isolating a bug in my JavaScript code for controlling Youtube videos via the ifram

I was having trouble isolating a bug in my JavaScript code for controlling Youtube videos via the iframe/HTML5 API.

I went back to the demo code on the main documentation page:

...and to my surprise, I see the same inconsistent behavior even when I use the demo code from there and don't change anything.

The behavior is that some of the time, when I load this page, the player autoplays (which is the intent of the code), and other times it doesn't. It always does succeed in loading. Also, the player never seems to stop after 6 seconds, in contrary to what the ments say.

Breakpoints verify that part of the issue at least is that onPlayerReady() is not always being called. When I set a breakpoint in onPlayerReady(), it usually is not reached, and is only reached the times that the player goes on to succeed in autoplaying.

Of course, this behavior may be dependent on the speed and reliability of my internet connection, which is wired and otherwise seems decently fast. I just tested it -- 24 Mbps, and it seems pretty consistent.

If I make superficial changes to the html, that seems to sometimes prompt the page on loading to autoplay, but not always. Sometimes I will reload every few seconds 5 times in a row with no autoplay or onPlayerReady breakpoint being hit, then do it a 6th time and that time it will autoplay fine.

I'm using Chrome v30.0.1599.101 on Mac OS 10.8.4.

I know that code is in beta and in flux, and isn't supposed to be production level yet, but I was hoping there was something i can try.

Here is the code I'm using, FYI, in case the code posted on the api reference page above changes. Again, I'm not altering a single character.

<!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 = "";
      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: '390',
          width: '640',
          videoId: 'M7lc1UVf-VE',
          events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange
          }
        });
      }

      // 4. The API will call this function when the video player is ready.
      function onPlayerReady(event) {
        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) {
        if (event.data == YT.PlayerState.PLAYING && !done) {
          setTimeout(stopVideo, 6000);
          done = true;
        }
      }
      function stopVideo() {
        player.stopVideo();
      }
    </script>
  </body>
</html>

I was having trouble isolating a bug in my JavaScript code for controlling Youtube videos via the iframe/HTML5 API.

I went back to the demo code on the main documentation page:

https://developers.google./youtube/iframe_api_reference

...and to my surprise, I see the same inconsistent behavior even when I use the demo code from there and don't change anything.

The behavior is that some of the time, when I load this page, the player autoplays (which is the intent of the code), and other times it doesn't. It always does succeed in loading. Also, the player never seems to stop after 6 seconds, in contrary to what the ments say.

Breakpoints verify that part of the issue at least is that onPlayerReady() is not always being called. When I set a breakpoint in onPlayerReady(), it usually is not reached, and is only reached the times that the player goes on to succeed in autoplaying.

Of course, this behavior may be dependent on the speed and reliability of my internet connection, which is wired and otherwise seems decently fast. I just tested it -- 24 Mbps, and it seems pretty consistent.

If I make superficial changes to the html, that seems to sometimes prompt the page on loading to autoplay, but not always. Sometimes I will reload every few seconds 5 times in a row with no autoplay or onPlayerReady breakpoint being hit, then do it a 6th time and that time it will autoplay fine.

I'm using Chrome v30.0.1599.101 on Mac OS 10.8.4.

I know that code is in beta and in flux, and isn't supposed to be production level yet, but I was hoping there was something i can try.

Here is the code I'm using, FYI, in case the code posted on the api reference page above changes. Again, I'm not altering a single character.

<!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./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: '390',
          width: '640',
          videoId: 'M7lc1UVf-VE',
          events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange
          }
        });
      }

      // 4. The API will call this function when the video player is ready.
      function onPlayerReady(event) {
        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) {
        if (event.data == YT.PlayerState.PLAYING && !done) {
          setTimeout(stopVideo, 6000);
          done = true;
        }
      }
      function stopVideo() {
        player.stopVideo();
      }
    </script>
  </body>
</html>
Share Improve this question edited Nov 1, 2013 at 17:53 Diosney 10.6k15 gold badges68 silver badges113 bronze badges asked Nov 1, 2013 at 17:50 Ben WheelerBen Wheeler 7,4242 gold badges48 silver badges58 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 2

I was opening the page locally, which makes for different behavior in all sorts of little ways from how it works when delivered from a server. The browser client itself handles things like cacheing differently when content is local. When I put the same page on a server, it started to work every time.

In addition, FYI, for my bigger issue that led me down this rabbithole, I found that I needed to follow this advice: https://stackoverflow./a/14952334/2308190 ...in order to get my YouTube callback functions to be called with jQuery loaded.

I had a situation where my first YouTube iframe would load correctly, and subsequent ones would not.

The issue was caused by creating a new YT.Player before its <div> had been added to the DOM. This issue didn't occur the first time I created a YT.Player, because the YouTube API had to be loaded first. This caused a microsecond delay which allowed the rest of my code to execute, so the <div> was added to the DOM before the YouTube API finished loading.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744976395a4604172.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信