For the last nine months I’ve been focused on the potential of HTML5 as an application development platform. When I first started talking about HTML5 for building apps, it seemed like very few people really “got” what it meant. Rather that HTML simply being something that gets spewed out by your server. HTML5 and it’s companion technologies, themselves became a platform.

In fairness, there were lots of developers that were starting to add “richness” to their HTML / client side work, predicated in no small part on the change in web development perspective that was catalyzed by the whole “Ajax” phenomenon.

More and more people seem to be embracing what the HTML5 wave of technologies could mean to development of all sorts. I say “could” mean because I believe HTML5 is in its “usable” infancy.

I recently asked my readers how important they think “off-line” support for HTML5 apps is.

The answers were great and showed how far developers as a group have advanced their perspective on where HTML development is going.

During my years at Microsoft I spent much time helping developers change the way that they looked at ASP.NET based web development by authoring patterns and practices that were focused on developing web applications that used real client / server interactions. With the advances Mozilla is making with it’s HTML5 Apps platform and the Firefox OS, it seems like a good time to apply that same kind of guidance to apps focused patterns and architectures.

So here is the beginning of a demo project for apps.

Understand that this app is a learning project and it’s focused on MozApps and Firefox OS apps. That means I’m writing the sample specificity for Gecko based run-times. If you were writing a cross browser app supporting Gecko, Webkit and Microsoft browsers you would have to do some feature detection and code against the features that are available in your browser. Perhaps I’ll write some samples to demonstrate that in the near future but for now I’ll focus on apps for one of the Gecko run-times.

Here is what the user interface of the demo looks like. I’ve only implemented the first feature for demonstrating “sometimes connected” architecture, but we’ll build on this app over the coming weeks.

Dynamic Media Demo

You can run the page here http://www.misfitgeek.com/demo/mediaget/ – just remember that this demo targets the Gecko run-time so if you’re not using a current version of Firefox you’re sort of on your own.

This page will play video files but what is a bit different about this page than you would have found in “old school” HTML page design is that the page contains a single media element and that HTML video tag has no video source specified.

This might be a common scenario in an HTML5 app (Think YouTube or Netflix). One would not, really could not, embed all the videos that the end user “might” want to watch.

In this case, we will not download any videos by default when the page is loaded, we’ll wait until the user selects a video to watch and then DYNAMICALLY fetch that video. When it was been retrieved we’ll play it. In our sample the user can choose from three videos but that number could be 100s of videos since none of the choices are actually downloaded until the user selects a video to watch.

At the top of the UI the user has three videos that they can choose from to watch.


</pre>
<h3>Videos Available For Viewing</h3>
<div class="gallery">
<div class="photo"><a href="javascript:loadMedia('demo-vid.webm');">
 <img src="img/foto.jpg" alt="" width="155" height="110" />
 </a>

 <a href="javascript:loadMedia('demo-vid.webm');">Fetch Video 1</a></div>
<div class="photo"><a href="javascript:loadMedia('demo-vid-2.webm');">
 <img src="img/foto.jpg" alt="" width="155" height="110" />
 </a>

 <a href="javascript:loadMedia('demo-vid-2.webm');">Fetch Video 2</a></div>
<div class="photo"><a href="javascript:loadMedia('demo-vid.webm');">
 <img src="img/foto.jpg" alt="" width="155" height="110" />
 </a>

 <a href="javascript:loadMedia('demo-vid.webm');">Fetch Video 3</a></div>
<div class="cleaner"></div>
</div>
<pre>

Notice that clicking on each image causes a bit of JavaScript to execute. (Yes I know there are other, and perhaps better ways to do this, especially if you are a jQuery aficionado but this is a straight forward method for learning simplicity.)

Here is what the loadMedia() method looks like.


function loadMedia(mediaFile) {
   document.getElementById("dlstatus-container").style.display="block";
   var xhr = new XMLHttpRequest();
   var mediaFileLocation = "media/" + mediaFile;
   xhr.open("GET", mediaFileLocation, true);
   xhr.responseType = "blob";      // Set the responseType to blob
   xhr.addEventListener("load", function () {
      if (xhr.status === 200) {
		 document.getElementById("dlstatus-container").style.display="none";
		 document.getElementById("player-container").style.display="block";
         blob = xhr.response;         
         var mediaFile = blob;
         var URL = window.URL || window.webkitURL;
         var mediaURL = URL.createObjectURL(mediaFile);
         var mediaElement = document.getElementById("media-element");
         mediaElement.setAttribute("src", mediaURL);
      }
      else {
		  // Download failed. Stop Download Status.
		  // ToDo: Add Error Handeling.
		  document.getElementById("dlstatus-container").style.display="none";
      }
   }, false);
   
   xhr.send();
}


The function catches a file name to be retrieved and then does an XmlHttpRequest call to fetch the file from the media directory on the server. Not that this method runs on the same thread as the user interface. In a later version we will use “HTML5 Web Workers” to cue the video downloads without blocking the user interface.

The first thing that loadMedia() does is show a hidden div named dlstatus-container. This div contains an animated gif file that indicates the file is being downloaded.


   <div id="dlstatus-container" style="display:none">
      <h2>Downloading Video .......</h2>
      <img src="img/dl-status.gif" alt=""  />
       </br /><br /><hr /><br />
   </div>

I use a free on line tool at AjaxLoad.info to generate the “working” image.

Line 7 in the listing above defines an event listener and line 8 tests to make sure the download was a success.

After that we turn off the status indicator div and the display the div that contains the HTML5 video element.


   <div id="player-container" style="display:none">
      <h2>Media Fetch</h2>
      <video id="media-element" controls="controls" 
             width="520" height="340" autoplay="autoplay">
      </video>
      </br /><br /><br /><hr /><br />
    </div>

Note that autoplay on the video element is on, so that when the video element’s source attribute is populated with the downloaded video on line 16 of the loadMedia() method, the video begins to play.

You can test the feature here – http://www.misfitgeek.com/demo/mediaget/

Note the behaviors.

  • If you start playing one video and then select another video, the first video will continue to play until your second choice is ready.
  • If you play one video, then play a second video, then go back to the fist video you watched – it will begin playing immediately when you select it, since it has been automatically cached by the run-time when it was downloaded.

A simple but meaningful feature.

Stay tuned. We’ll start adding features in the next post in this series.