title: Using Youtube's javascript API with jQuery
body: <p>I'm currently trying to use the YouTube API as part of a jQuery plugin and I've run into a bit of a problem.</p>
  
  <p>The way the YT api works is that you load the flash player and, when it's ready it will send a call back to a global function called <code>onYouTubePlayerReady(playerId)</code>. You can then use that id combined with <code>getElementById(playerId)</code> to send javascript calls into the flash player (ie, <code>player.playVideo();</code>).</p>
  
  <p>You can attach an event listener to the player with <code>player.addEventListener('onStateChange', 'playerState');</code> which will send any state changes to another global function (in this case <code>playerState</code>).</p>
  
  <p>The problem is I'm not sure how to associate a state change with a specific player. My jQuery plugin can happily attach more than one video to a selector and attach events to each one, but the moment a state actually changes I lose track of which player it happened in.</p>
  
  <p>I'm hoping some example code may make things a little clearer. The below code should work fine in any html file.</p>
  
  <pre><code>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;
  &lt;html&gt;
  &lt;head&gt;
    &lt;meta http-equiv="Content-Type" content="application/text+html;utf-8"/&gt;
  
    &lt;title&gt;Sandbox&lt;/title&gt;
  
    &lt;link type="text/css" href="http://jqueryui.com/latest/themes/base/ui.all.css" rel="stylesheet" /&gt;
  &lt;script type="text/javascript" src="http://www.google.com/jsapi"&gt;&lt;/script&gt;
  &lt;script type="text/javascript"&gt;
      google.load("jquery", "1.3.2");
      google.load("jqueryui", "1.7.0");
  &lt;/script&gt;
  &lt;script type="text/javascript" src="http://swfobject.googlecode.com/svn/tags/rc3/swfobject/src/swfobject.js"&gt;&lt;/script&gt;
  &lt;script type="text/javascript"&gt;
  (function($) {
      $.fn.simplified = function() {
          return this.each(function(i) {
              var params = { allowScriptAccess: "always" };
              var atts = { id: "ytplayer"+i };
              $div = $('&lt;div /&gt;').attr('id', "containerplayer"+i);
              swfobject.embedSWF("http://www.youtube.com/v/QTQfGd3G6dg&amp;enablejsapi=1&amp;playerapiid=ytplayer"+i, 
                                 "containerplayer"+i, "425", "356", "8", null, null, params, atts);
              $(this).append($div);
          });
      }
  })(jQuery);
  function onYouTubePlayerReady(playerId) {
      var player = $('#'+playerId)[0];
      player.addEventListener('onStateChange', 'playerState');
  }
  function playerState(state) {
      console.log(state);
  }
  
  $(document).ready(function() {
      $('.secondary').simplified();
  });
  &lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
      &lt;div id="container"&gt;
          &lt;div class="secondary"&gt;
  
          &lt;/div&gt;
          &lt;div class="secondary"&gt;
  
          &lt;/div&gt;
          &lt;div class="secondary"&gt;
  
          &lt;/div&gt;
          &lt;div class="secondary"&gt;
  
          &lt;/div&gt;
  
      &lt;/div&gt;
  &lt;/body&gt;
  
  &lt;/html&gt;
  </code></pre>
  
  <p>You'll see the console.log() outputtin information on the state changes, but, like I said, I don't know how to tell which player it's associated with. </p>
  
  <p>Anyone have any thoughts on a way around this?</p>
  
  <p>EDIT: 
  Sorry, I should also mentioned that I have tried wrapping the event call in a closure.</p>
  
  <pre><code>function onYouTubePlayerReady(playerId) {
      var player = $('#'+playerId)[0];
      player.addEventListener('onStateChange', function(state) { 
      return playerState(state, playerId, player); } );
  }
  
  function playerState(state, playerId, player) {
      console.log(state);
      console.log(playerId);
  }
  </code></pre>
  
  <p>In this situation <code>playerState</code> never gets called. Which is extra frustrating.</p>