views:

437

answers:

3

OK, I'm stuck and I don't know what's wrong even after following Google's docs and reading suggestions here on Stackoverflow. Why can't I control Youtube embeds in my web page?

If I create an HTML file with the <body> being:

<object id="o1" width="480" height="295">
  <param name="movie" 
    value="http://www.youtube.com/v/qCTLCNmnlKU&amp;hl=en_US&amp;fs=1&amp;enablejsapi=1&amp;"&gt;
  </param>
  <param name="allowFullScreen" value="true"></param>
  <param name="allowscriptaccess" value="always"></param>
  <embed id="e1" 
    src="http://www.youtube.com/v/qCTLCNmnlKU&amp;hl=en_US&amp;fs=1&amp;enablejsapi=1&amp;" 
    type="application/x-shockwave-flash" 
    allowscriptaccess="always" allowfullscreen="true" width="480" height="295">
  </embed>
</object>

Even when I attempt to do:

// I get an object. Yay.

document.getElementById('e1');

// This generates "...playVideo is not a function"

document.getElementById('e1').playVideo();

Help! What am I doing wrong? Thanks.

A: 

What happens if you use the id "o1" instead of "e1"?

OK well on this page: http://code.google.com/apis/youtube/js_api_reference.html it seems to me that the "swfobject" library needs to be included in order for that API to be available. I'll try it.

[edit] OK here's what I've got:

<html>
  <head>
    <script src='http://code.jquery.com/jquery-1.4.1.js'&gt;&lt;/script&gt;
    <script src='http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js'&gt;&lt;/script&gt;
    <script>
      window['onYouTubePlayerReady'] = function onYouTubePlayerReady(playerId) {
        player = document.getElementById("zebra");
        player.playVideo();
      };
      $(function() {
         swfobject.embedSWF(
         "http://www.youtube.com/v/qCTLCNmnlKU?hl=en_US&amp;fs=1&amp;enablejsapi=1&amp;playerapiid=ytplayer", 
          "foo",
          "480", "295",
          "8",
          null, null,
          { allowScriptAccess: 'always' },
          { id: 'zebra' }
        );
      });
    </script>
  </head>
  <body>
    <div id='foo'>Foo</div>
  </body>
</html>

This works, but oddly enough it only works when I serve it from a real web server. If I put that in a local file and load it up in the browser, it doesn't work. I don't know why but then I'm absolutely not a Flash expert, or a YouTube expert.

See http://gutfullofbeer.net/youtube.html (same as what's typed in above)

Pointy
Same difference. "... not a function."
Amy
OK well I've updated the answer
Pointy
According to:http://code.google.com/apis/youtube/js_api_reference.html "Note: To test any of these calls, you must have your file running on a webserver, as the Flash player restricts calls between local files and the internet."
Amy
@Pointy: (Btw thanks for your response. I didn't mean to sound terse; I was really frustrated.)
Amy
Hey no problem, I understand. (Also it didn't seem that terse to me.)
Pointy
+1  A: 

Youtube player hasn't yet been loaded at the time you're trying to use it. There is a special callback function that will be fired automatically as soon as it is loaded.

Your HTML pages that display the chromeless player must implement a callback function named onYouTubePlayerReady. The API will call this function when the player is fully loaded and the API is ready to receive calls.

by YouTube JavaScript Player API Reference.

Therefore you can rewrite your code in the following manner:

<script type="text/javascript">
function onYouTubePlayerReady(playerId) {
    var ytplayer = document.getElementById('e1');
    ytplayer.playVideo();
}
</script>

You can also mind passing playerapiid while embedding the player if there are plenty of them to distinguish in onYouTubePlayerReady handler.

Li0liQ
That doesn't ever fire when I set this up.
Pointy
Ah - things don't work if you load the file from local storage instead of from a real HTTP server. I don't know why.
Pointy
OK, I figured it out. The problem is the one statement on: http://code.google.com/apis/youtube/js_api_reference.html"Note: To test any of these calls, you must have your file running on a webserver, as the Flash player restricts calls between local files and the internet."
Amy
@Li0liQ: Thanks for the tip, but that doesn't work on localhost...
Amy
+1  A: 

OK, so here's the answer found in one tiny line of text on the API page: http://code.google.com/apis/youtube/js_api_reference.html

"Note: To test any of these calls, you must have your file running on a webserver, as the Flash player restricts calls between local files and the internet."

So to allow me to continue to develop on my Mac laptop I did the following:

  1. Edited my /etc/hosts file to include an entry back to my localhost:

    127.0.0.1   testhost.com
    
  2. Edited my /etc/apache2/httpd.conf file to add a virtual host entry pointing back to my development directory:

    <VirtualHost *:80>
        ServerName testhost.com
        DocumentRoot /Users/amy/flashproj
        <Directory /Users/amy/flashproj>
            AllowOverride all
            Options MultiViews Indexes FollowSymLinks
            Allow from All
        </Directory>
    </VirtualHost>
    
  3. Restarted Apache:

    sudo apachectl restart
    
  4. Browsed back to my own localhost via my new virtual server:

    http://testhost.com
    

Voila. That totally works now. I can query the page for the player:

document.getElementById('e1');                // OK
document.getElementById('e1').playVideo();    // OK!

Whew! No onYouTubePlayerReady() required either!

Amy
@Amy If API authors insist on implementing `onYouTubePlayerReady` it seems that it's the only way they expect their API to be used. No side effect may be seen on the localhost but they may appear on the internet because of slow internet connection or similar problems. E.g. I got your initial code working by inserting `alert('debug')` before getting element by id :)
Li0liQ
@Li0liQ: Good point. I still have quite a bit of testing to do so I'll post an update if anything new comes up.
Amy