HTML5, Video, Canvas, and Ext JS

January 14, 2010 by David Davis

HTML5 is coming. All of us at Ext are excited to embrace the new standard as it gains acceptance. This post will examine two notable HTML5 developments—Video and Canvas. The <video> tag allows for native video rendering, removing the current need for third-party plugins like Flash. Likewise, the <canvas> tag has a clean yet very powerful API allowing you to draw complex graphics at the pixel level.

As a part of HTML5, the <video> element can be customized and manipulated with CSS and JavaScript, giving us a great deal of control over how the video is presented to the user. With a little imagination we can create useful components, in this example we’ll create a “live video” thumbnail:

HTML5-video-screen-shot-desktop

The image above is an Ext JS web desktop, showing a video of an HTML5 video element in a window. Nothing too exciting… until you mouse over the taskbar button for the video player. Here, I have used a <canvas> tag to render a small preview which is live-updated from the actual video.

Building a HTML5 Video Window

In this installment, I’ll show you how to put a video element in a window and set up the preview quicktip using a fairly small amount of code.

We’ll start off with an extension to Ext.Panel which allows us to display HTML5 videos:

Ext.ns('Ext.ux');
 
/* -NOTICE-
 * For HTML5 video to work, your server must
 * send the right content type, for more info see:
 * https://developer.mozilla.org/En/HTML/Element/Video
 */
Ext.ux.HTML5VideoPanel = Ext.extend(Ext.Panel, {
 
  constructor: function(config) {
    Ext.ux.HTML5VideoPanel.superclass.constructor.call(this, Ext.applyIf(config, {
      width    : '100%',
      height   : '100%',
      autoplay : false,
      controls : true,
      bodyStyle: 'background-color:#000;color:#fff',
      html     : '',
      suggestChromeFrame: false
    }));
 
    this.on({
      scope        : this,
      render       : this._render,
      beforedestroy: function() {
        this.video = null;
      },
      bodyresize   : function(panel, width, height) {
        if (this.video)
        this.video.setSize(width, height);
      }
    });
  },
 
  _render: function() {
    var fallback = '';
 
    if (this.fallbackHTML) {
      fallback = this.fallbackHTML;
    } else {
      fallback = "Your browser doesn't support html5 video. ";
 
      if (Ext.isIE && this.suggestChromeFrame) {
        /* chromeframe requires that your site have a special tag in the header
         * see http://code.google.com/chrome/chromeframe/ for details
         */
        fallback += '<a>Get Google Chrome Frame for IE</a>';
      } else if (Ext.isChrome) {
        fallback += '<a>Upgrade Chrome</a>';
      } else if (Ext.isGecko) {
        fallback += '<a>Upgrade to Firefox 3.5</a>';
      } else {
        fallback += '<a>Get Firefox 3.5</a>';
      }
    }
 
    /* match the video size to the panel dimensions */
    var size = this.getSize();
 
    var cfg = Ext.copyTo({
      tag   : 'video',
      width : size.width,
      height: size.height
    },
    this, 'poster,start,loopstart,loopend,playcount,autobuffer,loop');
 
    /* just having the params exist enables them */
    if (this.autoplay) cfg.autoplay = 1;
    if (this.controls) cfg.controls = 1;
 
    /* handle multiple sources */
    if (Ext.isArray(this.src)) {
      cfg.children = [];
 
      for (var i = 0, len = this.src.length; i < len; i++) {
        if (!Ext.isObject(this.src[i])) {
          throw "source list passed to html5video panel must be an array of objects";
        }
 
        cfg.children.push(
          Ext.applyIf({tag: 'source'}, this.src[i])
        );
      }
 
      cfg.children.push({
        html: fallback
      });
 
    } else {
      cfg.src  = this.src;
      cfg.html = fallback;
    }
 
    this.video = this.body.createChild(cfg);
  }
 
});
 
Ext.reg('html5video', Ext.ux.HTML5VideoPanel);

You’ll notice that I’ve registered the extension as ‘html5video’. This will allow you to use xtype: ‘html5video’ in a panel or window. We’re going to use the Ext JS web desktop example. If you haven’t seen it already you can find it here.

Next we’ll add the html5video panel to a web desktop window, and the canvas preview to the taskbar button (you can follow along if you download Ext 3.0 and extract it on a web server, and edit sample.js in examples/desktop/).

Paste the html5 extension code above and the video window app below into the bottom of sample.js, or replace it with this version.

Desktop.VideoWindow = Ext.extend(Ext.app.Module, {
  id: 'video-win',
 
  init: function() {
    this.launcher = {
      text   : 'Video Window',
      iconCls: 'icon-grid',
      handler: this.createWindow,
      scope  : this
    };
  },
 
  createWindow: function() {
    var win,
        tipWidth  = 160,
        tipHeight = 96;
 
    /* createWindow uses renderTo, so it is immediately rendered */
    win = this.app.getDesktop().createWindow({
      animCollapse   : false,
      constrainHeader: true,
 
      title  : 'Video Window',
      width  : 740,
      height : 480,
      iconCls: 'icon-grid',
      shim   : false,
      border : false,
      layout : 'fit',
      items: [{
        xtype: 'html5video',
        src: [
        // firefox (ogg theora)
        {
          src : 'http://xant.us/files/google_main.ogv',
          type: 'video/ogg'
        },
        // chrome and webkit-nightly (h.264)
        {
          src : 'http://xant.us/files/google_main.mgv',
          type: 'video/mp4'
        }
        ],
        autobuffer: true,
        autoplay : true,
        controls : true,
        /* default */
        listeners: {
          afterrender: function() {
            var win = this.ownerCt;
            win.videoEl = this.video.dom;
 
            win.tip = new Ext.ToolTip({
              anchor   : 'bottom',
              autoHide : true,
              hideDelay: 300,
              height   : tipHeight,
              width    : tipWidth,
              bodyCfg  : {
                tag    : 'canvas',
                width  : tipWidth,
                height : tipHeight
              },
              listeners: {
                afterrender: function() {
                  /* get the canvas 2d context */
                  win.ctx = this.body.dom.getContext('2d');
                }
              }
            });
          }
        }
      }],
      listeners: {
        beforedestroy: function() {
          win.tip = win.ctx = win.videoEl = null;
        }
      }
    });
 
    win.show();
 
    win.tip.initTarget(win.taskButton.el);
    win.tip.on('show', this.renderPreview.createDelegate(this, [win]));
  },
 
  renderPreview: function(win) {
    if ((win.tip && ! win.tip.isVisible()) || !win.videoEl) return;
 
    if (win.ctx) {
      win.ctx.drawImage(win.videoEl, 0, 0, win.tip.width, win.tip.height);      
    }
 
    /* 20ms to keep the tooltip video smooth */
    this.renderPreview.defer(20, this, [win]);
  }
 
});

Now add the app constructor to getModules near the top of sample.js

getModules : function(){
  return [
    new MyDesktop.GridWindow(),
    new MyDesktop.TabWindow(),
    new MyDesktop.AccordionWindow(),
    new MyDesktop.BogusMenuModule(),
    new MyDesktop.BogusModule(),
    /* add the line below, and don't forget the comma above */
    new MyDesktop.VideoWindow()
  ];
}

In the source above, I have specified two files in the src param. This isn’t a playlist, but the video format fall back order. Not all browsers support the same formats so you have to include multiple sources, starting with the format that Firefox supports.

You can now open the web desktop example in Firefox 3.5+, or Google Chrome and go to Start->Video Window. This demo should also work on a webkit-nightly build (HTML5 video has yet to be added to Safari 4).

Here is the finished product.

Falling back

The HTML5 video tag allows for a general fallback in browsers that aren’t supported. The html5video Ext extension has an optional parameter, ‘fallbackHTML’. You can use this to provide your own message to upgrade or the flash player equivalent.

YouTube and HTML5 (webkit only)

YouTube provides a h.264 (mp4) source for any video. Although it isn’t obvious, you can get at the h.264 source url and pass that to the video tag. Unfortunately this doesn’t work for Firefox, and YouTube doesn’t provide an OGG Theora source. The YouTube HTML5 Viewer essentially creates an HTML5 video tag with the YouTube h.264 source.

Conclusion

Modern browers have implemented the the HTML5 video element even while HTML5 is still in the drafting stage.
Despite the issues with codec support, we can still use it and build tools around the API.

If you like this post, share it with your friends!

41 Responses to “HTML5, Video, Canvas, and Ext JS”

  1. Good stuff! HTML5 FTFW! :)

  2. jaranza says:

    EXTJS Rocks !!!

  3. Elvin says:

    Nice one
    Will this be avaible in EXT GWT?

  4. Walther says:

    This is genius stuff, incredible how little code it takes

  5. Henry D says:

    Very nice use of Ext to demonstrate its beauty.

  6. frank says:

    ext也染指HTML5了?貌似会在4.0中的蓝图的吧!?
    近来较闲,特此将该文译了一下,在:
    《非常HTML5预览:Video/Canvas/Ext JS》
    http://blog.csdn.net/zhangxin09/archive/2010/01/15/5192428.aspx

  7. Peter Thomas says:

    Check out the TinyOgg project, it exposes YouTube videos as Ogg:

    http://www.fsf.org/blogs/community/tinyogg

    Die Flash Die.

  8. frank says:

    I pick up this url from Ajaxian.com, the title is “Flash 11 should be a switch to JavaScript”
    http://thebackbutton.com/blog/93/flash-11-should-be-a-switch-to-javascript/

  9. Very nice use of the new HTML5 features. Looking forward to the day where we can leverage all these new capabilities without some browers (IE…) holding us back.

  10. luther.deng says:

    thank you Ext, and just go on please!

  11. mich says:

    This is genius stuff, incredible how little code it takes

  12. kapadokya says:

    Very nice use of Ext to demonstrate its beauty.

  13. David Davis says:

    Animal has posted an updated version of this over on the forums: http://www.extjs.com/forum/showthread.php?p=430137

  14. HTML5 and CSS3 is going to be the future and I hope Microsoft is going to implement more of that Webstandard into the IE9!

  15. Lucas says:

    Before to begin Html 5 features, please correct the Html 4 bugs.
    ExtJs have a lot of memory leak problems never solved with browser (most with firefox),
    If we add graphicals and videos functions, computers will burn alone without these corrections.

  16. t-shirts says:

    html5/css3 is a great promise but how long will it take before we can be sure all our surfers can see it?
    they just started to bury ie6 now, and looks like eternity until all surfers will be able to read html5/css3

  17. Diyet says:

    As a part of HTML5, the element can be customized and manipulated with CSS and JavaScript, giving us a great deal of control over how the video is presented to the user. With a little imagination we can create useful components, in this example we’ll create a “live video” thumbnail:

  18. Zayıflama says:

    html5/css3 is a great promise but how long will it take before we can be sure all our surfers can see it?

    As a part of HTML5, the element can be customized and manipulated with CSS and JavaScript, giving us a great deal of control over how the video is presented to the user. With a little imagination we can create useful components, in this example we’ll create a “live video” thumbnail:

  19. ExtJs have a lot of memory leak problems never solved with browser (most with firefox),
    If we add graphicals and videos functions, computers will burn alone without these corrections.


  20. /* match the video size to the panel dimensions */
    var size = this.getSize();

    var cfg = Ext.copyTo({
    tag : ‘video’,
    width : size.width,
    height: size.height
    },
    this, ‘poster,start,loopstart,loopend,playcount,autobuffer,loop’);

    /* just having the params exist enables them */

  21. /* match the video size to the panel dimensions */
    var size = this.getSize();

    var cfg = Ext.copyTo({
    tag : ‘video’,
    width : size.width,
    height: size.height
    },
    this, ‘poster,start,loopstart,loopend,playcount,autobuffer,loop’);

    /* just having the params exist enables them */

  22. oya-dantel says:

    Nice one
    Will this be avaible in EXT GWT?

  23. Animal says:

    @Dantel (both versions)

    Size is undefined at the onRender lifecycle point. You code will have no effect.

    The Video element size is synched on the onResize template method which is called upon a BoxComponent (or subclass thereof) on resize.

  24. efsiken says:

    Good one there Ext. Just one preoccupation: Does the Video Window also found in GXT?

  25. Dave says:

    I’m curious how Adobe will deal with the great HTML5 possibilities. Right now it looks like they want to keep the Flash, but at the end they have to switch too HTML5, I guess.

  26. quiero guardar una direccion en la bd pero no me guarda nada
    y cuando actualizo
    ejm:

    c:\nuevacarpeta\
    pero en la bd se actualiza de esa forma
    c:nuevacarpeta

  27. danielgos says:

    This is really some seriously awesome stuff – think it will work well for my project

  28. Good one there Ext. Just one preoccupation: Does the Video Window also found in GXT?

  29. ExtJs have a lot of memory leak problems never solved with browser (most with firefox),
    If we add graphicals and videos functions, computers will burn alone without these corrections.

  30. Very nice use of Ext to demonstrate its beauty.

  31. Jeux de foot says:

    Before to begin Html 5 features, please correct the Html 4 bugs.
    ExtJs have a lot of memory leak problems never solved with browser (most with firefox),
    If we add graphicals and videos functions, computers will burn alone without these corrections.

  32. tommy says:

    Nice one use of Ext to demonstrate its beauty.

  33. angel says:

    Good one there Ext

  34. thank you for share with us

  35. Bakugan Toys says:

    man thanks for this info!

  36. HTML5videoWanted says:

    Nice!
    Actually we are $ offering $ a contract for setting up HTML5 live video streaming. Anyone interested? Check out http://www.marss.co.uk/html5video

  37. kapadokya says:

    very good blog thanks for web..

Leave a Reply

© 2006-2010 Sencha Inc.