HTML5 media and non-HTML5 media

I'm spending almost all of my time these days on three Mozilla video projects: Popcorn.js, the Butter SDK, and the soon-to-be-beta Popcorn Maker tool.  Yesterday, after weeks of bug fixing and reviews, we hit code freeze for the 0.5 release of Butter and Popcorn Maker (due out in late June).  The 1.3 release of Popcorn.js is not far away either.

Among the many things I've been working on with these releases, one of them has gotten me sidetracked on a personal project.  Popcorn is fundamentally about using HTML5 media elements in order to dynamically alter web pages in time; or as Rick likes to say: web media does something at a given time with some information.  Popcorn, and its many plugins, allow a developer to easily script changes in a web page to times in some media resource.  Popcorn code looks like this:

// Wrap a media element in the page with Popcorn  
var p = Popcorn( "#video" )  
  // Add a subtitle  
    start: 0,  
    end: 10,  
    text: "This is a subtitle"  
  // Add an image  
    start: 15,  
    end: 45,  
    src: "",  
    target: "image-div"  
  // Get some Tweets from @popcornjs  
    start: 30,  
    end: 55,  
    src: "@popcornjs",  
    target: "tweets-div"  
  // Start the video!  

Here's a recent example of someone using it.  It's ridiculously easy to make complex time-based web experiences, or to create new plugins for doing complex things with simple syntax.

The problem is that lots of media floating around the web isn't HTML5 media.  There's a ton of Flash-based content, or things that use other plugins.  The good news is that it's getting better with every passing month, as more and more sites switch to HTML5 media.

Some time ago, in response to the realities of content creators, we decided to create a family of Popcorn Player plugins that would allow one to use things like YouTube, Vimeo, SoundCloud, etc. with Popcorn and its plugins.  None of the APIs these services offer are as rich as HTML5 Media Elements, but we found that we could hack our way to something approximating a Popcorn media resource.

The other day my student Robert and I were trying to debug some errors in the YouTube player plugin.  As we fixed one issue, another would crop up, and eventually I threw my hands up and decided to try something different: rather than trying to find bugs in the players via Popcorn, what if I implemented the HTML5 video spec in JS around the YouTube IFrame API?

My initial experiments with this have been very good.  I've managed to create a new wrapper, HTMLYouTubeVideoElement, which is a drop-in replacement for a <video> element.  With this I can steal <video> tests and make sure I'm doing what a <video> would do.  Best of all I can pass it into Popcorn without any extra work:

var p = Popcorn( new HTMLVideoElement( "#video" ) );

As far as Popcorn is concerned, this is an HTML5 media element, with all the usual events, properties, and methods.  On our Popcorn call today, David Ascher turned me onto x-tag.js and I quickly whipped up a new <x-video> element, which works identically to a <video>, but uses YouTube as the "decoder".  Check out the demo here.  Fun, right?

I've spent enough time over the past few years working through the HTML5 Media Elements spec to know that I'm not done, but the work thus far shows that this is doable.  My goal is to erase the API differences between using <video> and <audio> and all the various and sundry media types on the web.  We're trying to decide the best way to leverage this directly in Popcorn and Popcorn Maker, and future versions should include it.

For now it's one of those fun pieces of code I had to share.