oxjs/source/Ox.UI/js/Video/Ox.VideoPanelPlayer.js
2011-05-16 10:24:46 +02:00

432 lines
12 KiB
JavaScript

// vim: et:ts=4:sw=4:sts=4:ft=js
/*@
Ox.VideoPanelPlayer <f:Ox.Element> VideoPanelPlayer Object
() -> <f> VideoPanelPlayer Object
(options) -> <f> VideoPanelPlayer Object
(options, self) -> <f> VideoPanelPlayer Object
options <o> Options object
self <o> shared private variable
@*/
Ox.VideoPanelPlayer = function(options, self) {
var self = self || {},
that = new Ox.Element({}, self)
.defaults({
annotationsSize: 256,
duration: 0,
height: 0,
loop: false,
muted: false,
paused: false,
playInToOut: false,
points: [0, 0],
position: 0,
poster: '',
showAnnotations: true,
showControls: true,
subtitles: [],
videoHeight: 0,
videoSize: 'fit',
videoWidth: 0,
videoURL: '',
width: 0
})
.options(options || {})
.css({
height: self.options.height + 'px',
width: self.options.width + 'px'
})
.bindEvent({
resize: resizeElement,
key_shift_a: function() {
that.toggleAnnotations();
},
key_shift_c: function() {
that.toggleControls();
},
key_shift_s: function() {
that.toggleSize();
},
key_space: function() {
that.togglePlay();
}
});
$.extend(self, {
fullscreen: false,
videoCSS: getVideoCSS()
});
//alert(JSON.stringify([self.playerHeight, self.playerWidth, self.videoCSS]))
self.$player = new Ox.Element()
.css({
overflowX: 'hidden',
overflowY: 'hidden'
})
.bind({
mousedown: that.gainFocus
})
.bindEvent({
resize: resizeVideo
});
self.$video = new Ox.VideoElement({
height: self.videoCSS.height,
paused: true,
points: self.options.points,
position: self.options.position,
url: self.options.videoURL,
width: self.videoCSS.width
})
.css(self.videoCSS)
.bindEvent({
paused: paused,
playing: playing
})
.appendTo(self.$player);
self.$controls = new Ox.Element()
.bindEvent({
toggle: toggleControls
});
self.$buttons = new Ox.Element()
.css({
float: 'left',
width: '16px',
margin: '4px'
})
.appendTo(self.$controls);
self.$button = {
play: new Ox.Button({
id: 'play',
title: [
{id: 'play', title: 'play'},
{id: 'pause', title: 'pause'}
],
tooltip: ['Play', 'Pause'],
type: 'image'
})
.bindEvent({
click: self.$video.togglePlay
}),
mute: new Ox.Button({
id: 'mute',
title: [
{id: 'mute', title: 'mute'},
{id: 'unmute', title: 'unmute'}
],
tooltip: ['Mute', 'Unmute'],
type: 'image'
})
.bindEvent({
click: self.$video.toggleMute
}),
size: new Ox.Button({
id: 'size',
title: self.options.videoSize == 'fit' ? [
{id: 'fill', title: 'fill'},
{id: 'fit', title: 'fit'}
] : [
{id: 'fit', title: 'fit'},
{id: 'fill', title: 'fill'}
],
tooltip: self.options.videoSize == 'fit' ? [
'Fill Screen', 'Fit to Screen'
] : [
'Fit to Screen', 'Fill Screen'
],
type: 'image'
})
.bindEvent({
click: toggleSize
}),
fullscreen: new Ox.Button({
id: 'size',
title: [
{id: 'grow', title: 'grow'},
{id: 'shrink', title: 'shrink'}
],
tooltip: [
'Enter Fullscreen', 'Exit Fullscreen'
],
type: 'image'
})
.bindEvent({
click: toggleFullscreen
})
}
var i = 0;
Ox.forEach(self.$button, function($button) {
$button.css({
position: 'absolute',
left: '8px',
top: (8 + i++ * 24) + 'px'
})
.appendTo(self.$buttons);
});
self.$timelines = new Ox.Element()
.css({
float: 'left',
margin: '4px'
})
.appendTo(self.$controls);
self.$timeline = {
large: new Ox.LargeTimeline({
duration: self.options.duration,
position: self.options.position,
subtitles: self.options.subtitles,
videoId: self.options.videoId,
width: getTimelineWidth()
})
.css({
top: '4px'
})
.bindEvent({
change: changeLargeTimeline
}),
small: new Ox.SmallTimeline({
duration: self.options.duration,
position: self.options.position,
subtitles: self.options.subtitles,
videoId: self.options.videoId,
width: getTimelineWidth()
})
.css({
top: '76px'
})
.bindEvent({
change: changeSmallTimeline
})
};
Ox.forEach(self.$timeline, function($timeline) {
$timeline.appendTo(self.$timelines);
});
self.$panel = new Ox.SplitPanel({
elements: [
{
element: self.$player
},
{
collapsed: !self.options.showControls,
collapsible: true,
element: self.$controls,
size: 104
}
],
orientation: 'vertical'
})
.bindEvent({
resize: resizePanel
});
self.$annotations = new Ox.Element()
.bindEvent({
resize: resizeAnnotations,
resizeend: resizeendAnnotations,
toggle: toggleAnnotations
});
that.$element = new Ox.SplitPanel({
elements: [
{
element: self.$panel
},
{
collapsed: !self.options.showAnnotations,
collapsible: true,
element: self.$annotations,
resizable: true,
resize: [192, 256, 320, 384],
size: self.options.annotationsSize
}
],
orientation: 'horizontal'
});
function changeLargeTimeline(event, data) {
self.options.position = data.position;
self.$video.position(self.options.position);
self.$timeline.small.options({
position: self.options.position
});
}
function changeSmallTimeline(event, data) {
self.options.position = data.position;
self.$video.position(self.options.position);
self.$timeline.large.options({
position: self.options.position
});
}
function getPlayerHeight() {
return self.options.height -
self.options.showControls * 104 - 1;
}
function getPlayerWidth() {
return self.options.width -
(self.options.showAnnotations && !self.fullscreen) *
self.options.annotationsSize - 1;
}
function getTimelineWidth() {
return self.options.width -
(self.options.showAnnotations && !self.fullscreen) *
self.options.annotationsSize - 40
}
function getVideoCSS() {
var width = getPlayerWidth(),
height = getPlayerHeight(),
ratio = width / height,
videoRatio = self.options.videoWidth / self.options.videoHeight,
isWide = ratio < videoRatio;
return self.options.videoSize == 'fit' ? {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
width: (isWide ? width : Math.round(height * videoRatio)) + 'px',
height: (isWide ? Math.round(width / videoRatio) : height) + 'px',
margin: 'auto'
} : {
width: (isWide ? Math.round(height * videoRatio) : width) + 'px',
height: (isWide ? height : Math.round(width / videoRatio)) + 'px',
margin: [
isWide ? '0' : Math.floor((height - width / videoRatio) / 2) + 'px',
isWide ? Math.ceil((width - height * videoRatio) / 2) + 'px' : '0',
isWide ? '0' : Math.ceil((height - width / videoRatio) / 2) + 'px',
isWide ? Math.floor((width - height * videoRatio) / 2) + 'px' : '0'
].join(' ')
};
}
function paused() {
}
function playing(event, data) {
self.options.position = data.position;
self.$timeline.large.options({
position: self.options.position
});
self.$timeline.small.options({
position: self.options.position
});
}
function resizeAnnotations(event, data) {
self.options.annotationsSize = data;
resizeVideoAndControls();
}
function resizeendAnnotations(event, data) {
self.options.annotationsSize = data;
that.triggerEvent('change', {
annotationsSize: self.options.annotationsSize
});
}
function resizeControls() {
self.$timeline.large.options({
width: getTimelineWidth()
});
self.$timeline.small.options({
width: getTimelineWidth()
});
}
function resizeElement(event, data) {
// called on browser toggle
self.options.height = data;
resizeVideo();
}
function resizePanel(event, data) {
// called on annotations toggle
resizeVideoAndControls();
}
function resizeVideoAndControls() {
resizeVideo();
resizeControls();
}
function resizeVideo() {
self.videoCSS = getVideoCSS();
self.$video.css(self.videoCSS);
};
function toggleAnnotations(event, data) {
self.options.showAnnotations = !data.collapsed;
that.triggerEvent('change', {
showAnnotations: self.options.showAnnotations
});
}
function toggleControls(event, data) {
self.options.showControls = !data.collapsed;
that.triggerEvent('change', {
showControls: self.options.showControls
});
}
function toggleFullscreen() {
self.fullscreen = !self.fullscreen;
self.options.showAnnotations && that.$element.toggle(1);
self.fullscreen && self.options.showControls && self.$panel.toggle(1);
that.triggerEvent((self.fullscreen ? 'enter' : 'exit') + 'fullscreen', {});
}
function toggleSize() {
self.options.videoSize = self.options.videoSize == 'fit' ? 'fill' : 'fit';
resizeVideo();
that.triggerEvent('change', {
videoSize: self.options.videoSize
});
}
self.setOption = function(key, value) {
if (key == 'height') {
resizeVideo();
} else if (key == 'position') {
self.$video.position(value);
} else if (key == 'width') {
resizeVideoAndControls();
}
}
that.toggleAnnotations = function() {
that.$element.toggle(1);
//that.toggleAnnotations(null, !self.options.showAnnotations);
};
that.toggleControls = function() {
self.$panel.toggle(1);
//that.toggleControls(null, !self.options.showControls);
};
that.toggleMute = function() {
self.$button.mute.trigger('click');
};
that.togglePlay = function() {
self.$button.play.trigger('click');
};
that.toggleSize = function() {
self.$button.size.trigger('click');
}
return that;
}