HTML5, Video, Canvas, and Ext JS
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:
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).
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.











Good stuff! HTML5 FTFW! :)
EXTJS Rocks !!!
Nice one
Will this be avaible in EXT GWT?
This is genius stuff, incredible how little code it takes
Very nice use of Ext to demonstrate its beauty.
ext也染指HTML5了?貌似会在4.0中的蓝图的吧!?
近来较闲,特此将该文译了一下,在:
《非常HTML5预览:Video/Canvas/Ext JS》
http://blog.csdn.net/zhangxin09/archive/2010/01/15/5192428.aspx
Check out the TinyOgg project, it exposes YouTube videos as Ogg:
http://www.fsf.org/blogs/community/tinyogg
Die Flash Die.
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/
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.
thank you Ext, and just go on please!
This is genius stuff, incredible how little code it takes
Very nice use of Ext to demonstrate its beauty.
Animal has posted an updated version of this over on the forums: http://www.extjs.com/forum/showthread.php?p=430137
Here actually: http://www.extjs.com/forum/showthread.php?t=90379
HTML5 and CSS3 is going to be the future and I hope Microsoft is going to implement more of that Webstandard into the IE9!
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.
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
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:
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:
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.
…
/* 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 */
…
/* 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 */
Nice one
Will this be avaible in EXT GWT?
@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.
Good one there Ext. Just one preoccupation: Does the Video Window also found in GXT?
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.
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
This is really some seriously awesome stuff – think it will work well for my project
Good one there Ext. Just one preoccupation: Does the Video Window also found in GXT?
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.
Very nice use of Ext to demonstrate its beauty.
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.
Nice one use of Ext to demonstrate its beauty.
Good one there Ext
thank you for share with us
man thanks for this info!
Nice!
Actually we are $ offering $ a contract for setting up HTML5 live video streaming. Anyone interested? Check out http://www.marss.co.uk/html5video
very good blog thanks for web..