Wednesday, March 12th, 2008

YTranscript: Using the brand new YouTube chromeless, scriptable player

Category: JavaScript, Library

We saw a very exciting YouTube launch for developers today. People have long wanted to customize the YouTube player, and now you have complete control with a chromeless player that has JavaScript access so you can start, stop, go to a timing, and much more.

I took this API and implemented a simple DSL that allows me to build a simple transcript table of contents that lets you jump to a particular chapter in the video.

The HTML has special attributes and CSS classes, ending up like this:

  1. <div id="ytplayer" class="ytplayer" url=""></div>
  3. <div id="ytranscript" class="ytranscript" for="ytplayer">
  4. <b>Click on the item you want to skip too</b>
  5. <ul>
  6. <li starttime="0.0">Hand, hand, fingers, thumb</li>
  7. <li starttime="8.0">Drumming and drumming</li>
  8. <li starttime="28.0">Time to pick the apples and the plums</li>
  9. <li starttime="42.0">Enter Jake</li>
  10. <li starttime="44.0">Enter Jack</li>
  11. <li starttime="51.0">The monkeys say bye bye</li>
  13. <li starttime="60.0">Now they play bangos and fiddles</li>
  14. <li starttime="78.0">Wooah, millions of monkeys!</li>
  15. </ul>
  16. </div>

My JavaScript trivially attaches behaviour to the list to talk to the player. It adds timing information from the DSL to the HTML content, and uses seekTo to get the player to the point you need.


  1. window.onload = function() {
  2.   $$('.ytranscript').each(function(e) {
  3.     var player = e.readAttribute("for");
  4.     var playerEmbed = player + "Embed";
  5.     initPlayer(player, playerEmbed);
  7.     var lis = e.getElementsByTagName("li");
  8.     var odd = 1;
  9.     $A(lis).each(function(li) {
  10.       var starttime = li.readAttribute('starttime');
  11.       li.innerHTML = li.innerHTML + " <span class='timing'>" + parseInt(starttime) + " secs</span>";
  12.       li.addClassName( (odd++ % 2) ? "odd" : "even");
  13.       li.writeAttribute("title", "Send the player to this location");
  14.       li.onclick = function() {
  15.         makeSureVideoIsPlaying($(playerEmbed));
  16.         $(playerEmbed).seekTo(starttime, true);
  17.       };
  18.     });
  19.   });
  20. }
  22. function makeSureVideoIsPlaying(playerEmbed) {
  23.   if (playerEmbed.getState && $(playerEmbed).getState() == -1) { // -1 unstarted
  24.     playerEmbed.playVideo(); // play if we haven't started
  25.   }
  26. }
  28. function initPlayer(player, playerEmbed) {
  29.   var url = $(player).readAttribute('url');
  30.   var so = new SWFObject(url + "&enablejsapi=1&playerapiid=my" + playerEmbed, playerEmbed, 432, 400, 8);
  31.   so.addParam("AllowScriptAccess", "always");
  32.   so.write(player);
  33. }
  35. function onYouTubePlayerReady(playerId) {}

The one gotcha is that seekTo goes to the nearest keyframe, which can be a few seconds off. Hopefully it will at least go to the nearest one before the timing, but that isn’t the case right now.

Learn more

We have an interview with the engineers, and a bunch of documentation.

Check out the JavaScript API and chromeless player reference to find out more.

UPDATE: Christian Heilmann has written a video captioning system that lets you annotate as you pause.

Posted by Dion Almaer at 10:25 am

4 rating from 26 votes


Comments feed TrackBack URI

Nice to see another Javascript + Flash approach, should encourage people to get creative.

Comment by Scott Schiller — March 12, 2008

Meh, you still can’t jump forward to a position not yet loaded. And the keyframe thing…

Youtube seriously needs to catch up with other flash players on this.

Comment by Martin — March 12, 2008

It does not seem to be very useful because clicking on the video section links does not seem to be working to make the video jump forward.

IMHO YouTube video player is very week because it does not support setting initialTime parameter like Google Video Player. That is used by Google to rewrite the HTML tags of the video player when the user clicks on the links to seek the video to specific positions in seconds.

Once I asked YouTube if they were willing to support initialTime parameter, and they said they were not interested, which is a shame.

Comment by mlemos — March 12, 2008

Is anyone else having problems with Dion’s example and IE7?

Comment by kim3er — March 12, 2008

@kim3er, works great in firefox
but yes i too do have problems with it in IE7
shame, this would render this example useless by default.

but still a good start, maybe there is a fix for it. *shrug*

Comment by forsete — March 12, 2008

Great stuff,

I do have a slightly different question, I noticed with the ajaxian site that videos from youtube that are embedded into the site load after scrolling to that position in the document.

I am wondering how this is achieved? Is it some sort of javascript that detects if the video is in the viewport? Or is it something else?

Regards Robsworld

Comment by Robsworld — March 12, 2008

@robsworld YouTube had that feature for a while. It is a clever way of lazy loading. The YUI has an own control for that to allow you to only load images when they are visible.

Comment by Chris Heilmann — March 12, 2008

Dion, sorry if this is offtopic but currently I am unable to fetch specific VIdeo Feed for a given VideoID. I failed to find any feed which return a single “entry” details.

Comment by Adnan Siddiqi — March 14, 2008

What do y’all think of the “JW FLV Player” … I use it here to
similar effect in a blog post (by embedding appropriate javascript ahead of wysywyg-output html) —
— the one difference I note is that the JW FLV player doesn’t seem
to use times below the “second” increment in it’s javascript API (other than for smil/timed-text captions)) . I guess this makes the cueueing-to-nearest keyframe class of bug more of a feature…

Comment by NielsMayer — March 16, 2008

hi, can i use it for videos hostet by googlevideo?

Comment by harald22 — November 13, 2008

Leave a comment

You must be logged in to post a comment.