hacks.mozilla.org

Daily Archive for June 16th, 2009

an update on open video codecs and quality

Two days ago we posted a comparison by Greg Maxwell of low and medium resolution YouTube videos vs. Theora counterparts at the same bit rates. The result in that test was that Theora did much better at the low bit rate and more or less the same at the slightly higher bit rate. The conclusion being that Theora is perfectly appropriate for a site like YouTube.

Now Maik Merten has done the same with videos at HD resolution, comparing videos encoded by YouTube and a video encoded with the new Theora encoder at a managed bitrate. The results? Go have a look at the images in the post. Tell us if you can honestly see a major difference. We can’t.

H.264
Theora

audio player – HTML5 style

Last week we featured a demo from Alistair MacDonald (@F1LT3R) where he showed how to animate SVG with Canvas and a bunch of free tools. This week he has another demo for us that shows how you can use the new audio element in Firefox 3.5 with some canvas and JS to build a nice-looking audio player.

But what’s really interesting about this demo is not so much that it plays audio – lots of people have built audio players – but how it works. If you look at the source code for the page what you’ll find looks something like this:

<div id="jai">
  <canvas id="jai-transport" width="320" height="20"></canvas>
  <ul class="playlist">
    <li>
      <a href="@F1LT3R - Cryogenic Unrest.ogg">
        F1LT3R - Cryogenic Unrest
      </a>
      <audio src="@F1LT3R - Cryogenic Unrest.ogg"/>.
    <li>
      <a href="@F1LT3R - Ghosts in HyperSpace.ogg">
        F1LT3R - Ghosts in HyperSpace
      </a>
      <audio src="@F1LT3R - Ghosts in HyperSpace.ogg"/>.       
  </ul>    
</div>
(The actual list has fallbacks and is more compact – cleaned up here for easier reading.)

That’s right – the player above is just a simple HTML unordered list that happens to include audio elements and is styled with CSS. You’ll notice that if you right click on one of them that it has all the usual items – save as, bookmark this link, copy this link location, etc. You can even poke at it with Firebug.

The JavaScript driver that Al has written will look for a <div> element with the jai ID and then look for any audio elements that are inside it. It then will draw the playback interface in the canvas at the top of the list. The playback interface is built with simple JS canvas calls and an SVG-derived font.

Using this driver it’s super-easy to add an audio player to any web site by just defining a canvas and a list. Much like what we’ve seen on a lot of the web with the rise of useful libraries like jQuery, this library can add additional value to easily-defined markup. Another win for HTML5 and the library model.

Al has a much larger write-up on the same page as the demo. If you haven’t read through it you should now.

(Also? Al wrote the music himself. So awesome.)

better security and performance with native JSON

The JavaScript Object Notation (JSON) mechanism for representing data has rapidly become an indispensable part of the web developer’s toolkit, allowing JavaScript applications to obtain and parse data intuitively, within scripts, with lightweight data encapsulation. Firefox 3.5 includes support for JSON natively by exposing a new primitive — window.JSON — to the top level object.

Native “out of the box” support for JSON comes to the web courtesy of the ECMAScript 5th Edition (PDF link to specification), other aspects of which will also be supported by Firefox 3.5. Presently, native JSON is supported by Firefox 3.5 and IE8, with a strong likelihood of other browsers supporting it soon as well.

Native JSON support has two advantages:

  1. Safety. Simply using eval to evaluate expressions returned as strings raises security issues. Also, the native JSON primitive can only work with data. It can’t be used to parse objects with method calls; attempting to do so returns an error.
  2. Performance. Parsing JSON safely, using third-party scripts and libraries, is likely to be slower than native JSON parsing within the browser.

Let’s look at some examples.

A JSON API for search results might look like this:

/* 
Assume that you obtained var data
as a string from a server
For convenience we display this search
result on separate lines
*/
 
var data = ' { "responseData":
{"results": [
    {
        "SafeSearch":"true",
        "url":"http://www.arunranga.com/i.jpg",
    },
    {
        "SafeSearch":"false",
	 "url":"http://www.badarunranga.com/evil.jpg",
    }
]}}';

Such a resource could be returned by a simple HTTP GET request using a RESTful API.

Using native JSON, you could do something like this:

/* 
 Obtain a handle to the above JSON resource
 This is best and most conveniently done
 via third-party libraries that support native JSON
*/
 
if (window.JSON) {
    var searchObj = JSON.parse(data);
    for (var i=0; i++; i < searchObj.responseData.results.length) {
        if (searchObj.responseData.results[i].SafeSearch) {
            var img = new Image();
            img.src = searchObj.responseData.results[i].url;
            // ... Insert image into DOM ...
    }
}

You can also stringify the object back to the string:

// Back to where we started from
 
var data = JSON.stringify(searchObj);
 
// data now holds the string we started with

Of course, to really enable the power of JSON, you’ll want to retrieve JSON resources from different domains, via callback mechanisms like JSONP. Many web developers are unlikely to use the JSON primitive directly. Rather, they’ll use them within libraries such as Dojo and jQuery. These libraries allow for the retrieval and direct parsing of JSON resources from different domains, and add a great deal of syntactic sugar to the process of callbacks and DOM insertions.

The native JSON primitive works with the popular json2.js library (which correctly detects if native JSON is enabled), so developers can seamlessly use JSON parsing on browsers that don’t support native JSON. As of this writing, Dojo and jQuery have committed to supporting native JSON: