title: Safari 11 / YouTube API bug. Rapid play/pause and failure to autoplay
body: <p>This just started getting reported to me by users. I spent a bunch of time exploring my own code for bugs, but it seems like it's related specifically to <strong>Safari 11</strong> <em>(newest)</em>.</p>
  
  <p>When using a simple example of the YouTube IFrame Embed API, Safari will rapidly switch between states of play and pause until it ends up on pause.</p>
  
  <p>This is not the most optimized version of the example because there was some exploration in here as to what might make it work. I wanted to skip ahead and autoplay, but it wouldn't work the way it's supposed to. I tried using <code>start</code> and <code>playVideo</code> which are documented YT API examples.</p>
  
  <p>I've only recently confirmed this to be a bug which explains why there's some verbose parameters in the example.</p>
  
  <p>Notes:</p>
  
  <ul>
  <li>Sometimes the video WILL play depending on how many times you refresh, but it's very infrequent.</li>
  <li>Autoplay flags usually fail.</li>
  <li>Using <code>start</code> flag in this example to skip forward because <code>startSeconds</code> was not working.</li>
  <li>Code example works in other browsers: <code>Chrome</code>, <code>Opera</code>, <code>Firefox</code></li>
  </ul>
  
  <p>Here's an image of what you might see in Safari's console, which shows the Player State panic, eventually landing on 2 (<em>paused</em>). <a href="https://i.stack.imgur.com/2WmSO.png" rel="noreferrer"><img src="https://i.stack.imgur.com/2WmSO.png" alt="Panic in the console"></a></p>
  
  <p>Here's a copy/paste code sample that will replicate the bug. Drop it in any HTML file and you should see it fail in Safari 11. </p>
  
  <pre><code>&lt;style&gt;
      body, html, iframe {
          position: absolute; left: 0; right: 0; top: 0; bottom: 0; width: 100%; height: 100%;
          margin: 0;
          padding: 0;
          pointer-events: none;
      }
  &lt;/style&gt;
  
  
  &lt;script&gt;
      var videoId = "9nwQ1F7oX-8";
  
      var playerVars = {
          autohide: 1,
          autopause: 0,
          autoplay: 1,
          cc_load_policy: "0",
          disablekb: 1,
          enablejsapi: 1,
          iv_load_policy: 1,
          modestbranding: 1,
          origin: "*",
          rel: 0,
          showinfo: 0,
          start: 122,
          version: 3
      };
  &lt;/script&gt;
  
  
  &lt;iframe id="ytplayer"
      frameborder="0"
      allowfullscreen="1"
      title="YouTube video player"
      width="100%"
      height="100%"
      x-src="https://www.youtube.com/embed/9nwQ1F7oX-8?enablejsapi=1&amp;amp;origin=*&amp;amp;rel=0&amp;amp;version=3&amp;amp;iv_load_policy=3&amp;amp;modestbranding=1&amp;amp;showinfo=0&amp;amp;autohide=1&amp;amp;disablekb=1&amp;amp;autoplay=1&amp;amp;autopause=0&amp;amp;cc_load_policy=0&amp;amp;startSeconds=30&amp;amp;widgetid=1"
      src="https://www.youtube.com/embed/9nwQ1F7oX-8?enablejsapi=1&amp;amp;origin=*&amp;amp;start=122"&gt;
  &lt;/iframe&gt;
  
  
  &lt;script&gt;
  window.onYouTubeIframeAPIReady = function() {
      console.log("YouTube is ready!", videoId, playerVars);
  
      var api = new YT.Player("ytplayer", {
          width: "100%",
          height: "100%",
          videoId: videoId,
          playerVars: playerVars,
          events: {
  
              onError: function(e) {
                  // 100 â€“ The video requested was not found. This error occurs when a video has been removed (for any reason) or has been marked as private.
                  // 101 â€“ The owner of the requested video does not allow it to be played in embedded players.
                  // 150 â€“ This error is the same as 101. It"s just a 101 error in disguise!
  
                  console.warn("An error has occurred", arguments);
              },
  
              onReady: function() {
                  // log
                  console.log("YouTube player is ready to use");
  
                  //
                  api.playVideo();
              },
  
              onStateChange: function(e) {
                  // log
                  console.log("YouTube state change ", e);
  
                  // Finished
                  if (e.data == 0) {
                      console.log("Finished");
                  }
  
                  // Playing
                  else if (e.data === YT.PlayerState.PLAYING) {
                      console.log("Playing");
                  }
  
                  // Pausing
                  else if (e.data === 2) {
                      console.log("Pausing");
                  }
  
                  // Buffering
                  else if (e.data === 3) {
                      console.log("Buffering");
                  }
              }
          }
      });
  
  }
  &lt;/script&gt;
  
  &lt;script src="https://www.youtube.com/iframe_api"&gt;&lt;/script&gt;
  </code></pre>