PDA

View Full Version : HTML5 VideoPanel based on Xantus's blog posting.



Animal
22 Jan 2010, 12:38 PM
It seemed easy after Dave (forum poster Xantus) showed the way, so...

I took Dave's code and tweaked it to conform to recommendations about subclassing Ext Components: http://www.extjs.com/learn/Tutorial:Creating_new_UI_controls

I also encapsulated the creation of a preview Tooltip within the class. The updating of the preview to create the appearance of a little moving video is provided by Ext.TaskMgr.



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, {

// Provide defaults for configurable tip sizes.
tipWidth: 160,
tipHeight: 96,

autoHidePreview: false,

constructor: function(config) {
Ext.ux.HTML5VideoPanel.superclass.constructor.call(this, Ext.applyIf(config, {
autoplay : false,
controls : true,
bodyStyle: 'background-color:#000;color:#fff',
suggestChromeFrame: false
}));
},

onRender: 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>';
}
}

// Configure the body element to be a <video> element
this.bodyCfg = Ext.copyTo({
tag : 'video',
children: []
},
this, 'poster,start,loopstart,loopend,playcount,autobuffer,loop');

// Truthy params enables them
if (this.autoplay) this.bodyCfg.autoplay = 1;
if (this.controls) this.bodyCfg.controls = 1;

// Handle multiple sources
if (Ext.isArray(this.src)) {
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";
}
this.bodyCfg.children.push(
Ext.applyIf({tag: 'source'}, this.src[i])
);
}
this.bodyCfg.children.push({
html: fallback
});
} else {
this.bodyCfg.src = this.src;
this.bodyCfg.html = fallback;
}
Ext.ux.HTML5VideoPanel.superclass.onRender.apply(this, arguments);
this.video = this.body;
},

onResize: function() {
Ext.ux.HTML5VideoPanel.superclass.onResize.apply(this, arguments);
Ext.apply(this.body.dom, this.body.getSize());
},

onDestroy: function() {
Ext.ux.HTML5VideoPanel.superclass.onDestroy.apply(this, arguments);
if (this.tooltip) {
delete this.tipCtx;
this.tooltip.destroy();
Ext.TaskMgr.stop(this.tipUpdateTask);
}
},

getPreviewer: function() {
if (!this.tooltip) {
this.tooltip = new Ext.ToolTip({
anchor : 'bottom',
autoHide : this.autoHidePreview,
hideDelay: Ext.num(this.hidePreviewDelay, Number.MAX_VALUE),
height : this.tipHeight,
width : this.tipWidth,
bodyCfg : {
tag : 'canvas',
width : this.tipWidth,
height : this.tipHeight
},
listeners: {
render: this.onTipRender,
show: this.onTipShow,
hide: this.onTipHide,
scope: this
}
});

// Task to keep the tip updated while it is visible
this.tipUpdateTask = {
run: this.updatePreview,
interval: 20,
scope: this
};
}
return this.tooltip;
},

onTipRender: function() {
this.tipCtx = this.tooltip.body.dom.getContext('2d');
},

onTipShow: function() {
Ext.TaskMgr.start(this.tipUpdateTask);
},

onTipHide: function() {
Ext.TaskMgr.stop(this.tipUpdateTask);
},

updatePreview: function() {
if (this.tipCtx) {
this.tipCtx.drawImage(this.body.dom, 0, 0, this.tipWidth, this.tipHeight);
}
}
});
Ext.reg('html5video', Ext.ux.HTML5VideoPanel);


This means that to get it working in a desktop, all you do is add the line in red:



getModules : function(){
return [
new MyDesktop.GridWindow(),
new MyDesktop.TabWindow(),
new MyDesktop.AccordionWindow(),
new MyDesktop.BogusMenuModule(),
new MyDesktop.BogusModule(),
new MyDesktop.VideoWindow()
];
},


And create the module:



MyDesktop.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 () {
/* 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',
ref: 'videoPanel', // put a reference in the Window
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
}
});
win.show();
// Hook up the provided preview tooltip to our TaskBar button
win.videoPanel.getPreviewer().initTarget(win.taskButton.el);
}
});

xantus
22 Jan 2010, 3:25 PM
Thanks Animal!

I've been meaning to update the blog post, but I've been pretty busy. :)

mitchellsimoens
28 Mar 2010, 6:02 PM
Of course if you didn't want to use it in the Desktop example you can...

Ext.ux.HTML5VideoPanel.js:

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);

test.js:

var win = new Ext.Window({
animCollapse : false,
constrainHeader: true,
title : 'Video Window',
width : 740,
height : 480,
shim : false,
border : false,
layout : 'fit',
items: [{
xtype: 'html5video',
src: [{
src : 'video.mp4',
type: 'video/mp4'
}],
autobuffer: true,
autoplay : true,
controls : true
}]
}).show();

mr-romaniko
9 May 2010, 11:57 PM
how to make this????
http://b.pix.ge/o/ubv8v.png (http://pix.ge/)

Animal
10 May 2010, 4:04 AM
Call getPreviewer

mr-romaniko
10 May 2010, 11:12 AM
can you explain to me more circumstantially?
please

mdineshkumarcs
2 Jul 2010, 4:17 AM
src: 'http://xant.us/files/google_main.ogv',
type: 'video/ogg'

Here i want to set my youtube URL and also set type. IS IT POSSIBLE ?

mitchellsimoens
3 Jul 2010, 5:54 PM
Here i want to set my youtube URL and also set type. IS IT POSSIBLE ?

Have you tried it?

xbboys
20 Sep 2010, 12:28 AM
Hi everyone,

I am looking forward to do something similar but on a normal extjs window without video. Something like Win Vista. Do you think it is possible?

Animal
20 Sep 2010, 1:16 AM
Is that some weird spam?

Because it doesn't make any sense.