title: YouTube Iframe Api Javascript Errors because of loading time
body: <p>I am currently implementing the Youtube iFrame API into my website. It's all working pretty neet. Everything is working, all functions work but I still get javascript errors.</p>
  
  <p>The functions don't destroy any of the functionality or anything on the website, and all the functions do their jobs. The errors say they don't recognise the YT functions.</p>
  
  <p>Error 1:</p>
  
  <pre><code>Uncaught TypeError: Cannot read property 'getDuration' of undefined
  </code></pre>
  
  <p>Code that causes error 1 (endSeconds and startSeconds are correctly defined: </p>
  
  <pre><code>var duration = player.getDuration() - (player.getDuration() - endSeconds) - startSeconds;
  </code></pre>
  
  <p>Error 2:</p>
  
  <pre><code>Uncaught TypeError: Cannot read property 'mute' of undefined 
  </code></pre>
  
  <p>Code that causes error 1</p>
  
  <pre><code>player.mute();
  </code></pre>
  
  <p>getDuration() and mute() are both functions as the API describes, and as I told, the functionality works. So my question is why I get these errors, and I would like some help to fix them.</p>
  
  <hr>
  
  <p>For the context I will include parts of the html &amp; js code down here</p>
  
  <p>HTML</p>
  
  <pre><code>&lt;aside class="showcase"&gt;
      &lt;div id="player"&gt;&lt;/div&gt;
      &lt;div class="grid"&gt;
          &lt;div class="eq"&gt;&lt;/div&gt;
          &lt;div class="timebar"&gt;
              &lt;div vlass="current_time"&gt;&lt;/div&gt;
          &lt;/div&gt;
      &lt;/div&gt;
  &lt;/aside&gt;
  </code></pre>
  
  <p>JS</p>
  
  <pre><code>/* Load the player */
      var tag = document.createElement('script');
      tag.src = "https://www.youtube.com/iframe_api";
      var firstScriptTag = document.getElementsByTagName('script')[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
      var done = false;
      var player;
      var videoId = 'A3PDXmYoF5U';
      var startSeconds = 5;
      var endSeconds = 293;
      var setVolume = 15;
      var suggestedQuality = 'large';
      function onYouTubeIframeAPIReady() {
            player = new YT.Player('player', {
            height:  ($(window).width() / 16) * 9 + 35,
            width: '100%',
            events: {
              'onReady': onPlayerReady,
              'onStateChange': onPlayerStateChange
            }
          });
      }
  
      function onPlayerReady(evt) {
          player.loadVideoById({'videoId': videoId, 'startSeconds': startSeconds, 'endSeconds': endSeconds, 'suggestedQuality': suggestedQuality });
          evt.target.playVideo();
      }
  
      /* Soundcheck */
      function onPlayerStateChange(event) {
          var done = false;
  
          if (event.data == YT.PlayerState.PLAYING &amp;&amp; !done) {
              if (player.isMuted()){
                  $(".eq").addClass("mute");  
              }
  
              if (player.getVolume() &gt; setVolume) {
                  player.setVolume(setVolume);
              } 
              done = true;
          }
  
          /* Loop function */
          if (event.data == YT.PlayerState.ENDED &amp;&amp; !done) {
              player.seekTo(startSeconds, true);
              done = true;
          }
       }
  
      /* Reponsive sizes */ 
      $(document).on("ready", function() {
          $(window).on("resize", function() {
              $(".showcase iframe").attr("height", ($(window).width() / 16) * 9 + 35 );
  
              $(".showcase").css({
                  "height": (($(window).width() / 16) * 9 + 35) + "px",
                  "max-height": ( $(window).height() + 39 - 26) + "px"
              });
  
              $(".admin-bar .showcase").css({
                  "max-height": ( $(window).height() + 39 - 58) + "px"
              });
          }).trigger("resize")        
      }).trigger("ready")
  
      /* Timebar */
      window.setInterval(function(){
          var duration = player.getDuration() - (player.getDuration() - endSeconds) - startSeconds;
          var currentTime = player.getCurrentTime() - startSeconds;
          $(".current_time").css({
              "width": ( currentTime / duration ) * 100 + "%"
          });
      }, 100);
  
  
      /* Mute button */
      $(".eq").on("click", function(){
          if( $(".eq").hasClass("mute")) {
              player.unMute();
              $(".eq").removeClass("mute");
          } else {
              player.mute();
              $(".eq").addClass("mute");
          }
      }).trigger("click")
  </code></pre>